Ando buscando las descargas del "Sistema de Campañas" de xprocess09

Lukih

Soñador
Colaborador
Buenas gente, hace rato que estoy buscando las descargas de este aporte https://www.gs-zone.org/temas/sistema-de-campanas-super-completo.87570/ hecho por @xprocess09 pero parecen estar extintas del internet.

Este post es un intento de 1% de posibilidades 99% de fe.

Nada, si alguno es un enfermo coleccionista de aportes y tiene las cositas me daría una re mano subiéndomelo, es un código re interesante el que se mandó el tipo la verdad.

Saludos y espero recibir algunas palabras de consuelo antes de que me cierren el tema XD.
 
Última edición:

About

Director del Proyecto
Codigo modCampaings:
Option Explicit

Public Sub LoadCampaigns()

Dim tDesc                       As Boolean
Dim i                           As Long
Dim S                           As Long
Dim LoopA                       As Long
Dim LoopB                       As Long
Dim tRecompensa                 As New clsFastString
Dim Leer                        As New clsIniReader

10  On Error GoTo ErrHandler

20  Call WriteToConsole("Cargando campañas...")
    '    If frmCargando.Visible Then
    '        'frmCargando.Label1(2).Caption = "Cargando Campaings.AO"
    '    End If

30  If FileExist(DatPath & "Campaigns.AO", vbNormal) Then

        '/////////////////////////////////////////READ//BEGIN//////////////////////////////////////////////

40      Call Leer.Initialize(DatPath & "Campaigns.AO")

50      Set LeerCampaigns = Leer

60      NumCampaigns = val(Leer.GetValue("INIT", "NumCampaigns"))

70      ReDim Campaign(1 To NumCampaigns) As Campaign

80      For i = 1 To NumCampaigns

90          With Campaign(i)

                '////////////////////////////////////////READ//PROPERTIES//////////////////////////////////////////

100             With .Properties
110                 .Name = Leer.GetValue("Campaign" & i, "Name")
                    '            .Description = Leer.GetValue("Campaign" & i, "Description")    'Cambio de lugar la descripción, así podemos cargarla automáticamente.
                    '            .Description = .Description &  ")" 'Cierro el paréntesis aca.
120                 .Dialog.FirstTalk = Leer.GetValue("Campaign" & i, "Dialog1")
130                 .Dialog.SecondTalk = Leer.GetValue("Campaign" & i, "Dialog2")
140                 .Dialog.ThirdTalk = Leer.GetValue("Campaign" & i, "Dialog3")
150                 .Dialog.FourthTalk = Leer.GetValue("Campaign" & i, "Dialog4")
160                 .Dialog.FifthTalk = Leer.GetValue("Campaign" & i, "Dialog5")
170                 .NumStages = val(Leer.GetValue("Campaign" & i, "NumStages"))
180                 .Redoable = IIf(val(Leer.GetValue("Campaign" & i, "Redoable")) <> 0, True, False)
190                 .Timing = val(Leer.GetValue("Campaign" & i, "Time"))
200                 .FinishWhenDie = val(Leer.GetValue("Campaign" & i, "FinishWhenDie"))
210                 .FinishWhenDisconnect = val(Leer.GetValue("Campaign" & i, "FinishWhenDisconnect"))
220             End With

                '////////////////////////////////////////READ//REQUIREMENTS////////////////////////////////////////

230             With .Requirements
240                 .MinLvl = val(Leer.GetValue("Campaign" & i, "MinLvl"))
250                 .MaxLvl = val(Leer.GetValue("Campaign" & i, "MaxLvl"))
260                 .PreviousCampaign = val(Leer.GetValue("Campaign" & i, "PreviousCampaign"))
270                 .Class = val(Leer.GetValue("Campaign" & i, "Class"))
280                 .Race = val(Leer.GetValue("Campaign" & i, "Race"))
290                 .Genre = val(Leer.GetValue("Campaign" & i, "Genre"))
300                 .Alignment = val(Leer.GetValue("Campaign" & i, "Alignment"))
310                 .Faction = val(Leer.GetValue("Campaign" & i, "FACTION"))
320                 .Rank = val(Leer.GetValue("Campaign" & i, "Rank"))
330                 If .MinLvl > .MaxLvl And .MaxLvl > 0 Then .MinLvl = .MaxLvl

340             End With

                '/////////////////////////////////////////READ//REWARDS////////////////////////////////////////////

350             With .Rewards
360                 .PlateCoins = val(Leer.GetValue("Campaign" & i, "PlateCoins"))
370                 .EnlistFaction = val(Leer.GetValue("Campaign" & i, "EnlistFaction"))    '0 = Nada, 1 Armada, 2 Caos
380                 .Forgive = val(Leer.GetValue("Campaign" & i, "Forgive"))    'Perdon a los PKS!
390                 .RewardExp = val(Leer.GetValue("Campaign" & i, "RewardExp"))
400                 .RewardGold = val(Leer.GetValue("Campaign" & i, "RewardGold"))
410                 .NumRewardObj = val(Leer.GetValue("Campaign" & i, "NumRewardObj"))

420                 .RewardByClass = val(Leer.GetValue("Campaign" & i, "RewardByClass"))
430                 .NumRewardObjByClass = val(Leer.GetValue("Campaign" & i, "NumRewardObjByClass"))    'Cantidad de premios por clase, que van a recibir TODAS las clases. Siempre es la misma cantidad de premios para todas en una misma misión.

440                 tRecompensa.Clear

450                 If Campaign(i).Properties.FinishWhenDie Then
460                     If Len(tRecompensa.Value) = 0 Then
470                         tRecompensa.Append " INFO: Ésta mision se cancela al MORIR"
480                     Else
490                         tRecompensa.Append ", INFO: ésta mision se cancela al MORIR."
500                     End If
510                 End If

520                 If Campaign(i).Properties.FinishWhenDisconnect Then
530                     If Len(tRecompensa.Value) = 0 Then
540                         tRecompensa.Append " INFO: Ésta mision se cancela al DESCONECTARSE del juego."
550                     Else
560                         tRecompensa.Append ", INFO: ésta mision se cancela al DESCONECTARSE del juego."
570                     End If
580                 End If

590                 If Campaign(i).Properties.Timing > 0 Then
600                     If Len(tRecompensa.Value) = 0 Then
610                         tRecompensa.Append " INFO: Debes realizar la misión en menos de " & IIf(Campaign(i).Properties.Timing > 60, Campaign(i).Properties.Timing / 60 & " min.", Campaign(i).Properties.Timing & " seg.")
620                     Else
630                         tRecompensa.Append ", INFO: Debes realizar la misión en menos de " & IIf(Campaign(i).Properties.Timing > 60, Campaign(i).Properties.Timing / 60 & " min.", Campaign(i).Properties.Timing & " seg.")
640                     End If
650                 End If

660                 If .RewardExp > 0 Then
670                     If Len(tRecompensa.Value) = 0 Then
680                         tRecompensa.Append "Recompensa: " & .RewardExp & " de Experiencia"
690                     Else
700                         tRecompensa.Append ", " & .RewardExp & " de Experiencia"
710                     End If
720                 End If

730                 If .RewardGold > 0 Then
740                     If Len(tRecompensa.Value) = 0 Then
750                         tRecompensa.Append "Recompensa: " & .RewardGold & " de Oro"
760                     Else
770                         tRecompensa.Append ", " & .RewardGold & " de Oro"
780                     End If
790                 End If

800                 If .Forgive = 1 Then
810                     If Len(tRecompensa.Value) = 0 Then
820                         tRecompensa.Append "Recompensa: Volverás a ser Ciudadano"
830                     Else
840                         tRecompensa.Append ", y Volverás a ser Ciudadano"
850                     End If
860                 End If

870                 Select Case .EnlistFaction
                        Case 1

880                         If Len(tRecompensa.Value) = 0 Then
890                             If BonusExpArmy > 0 Then
900                                 tRecompensa.Append "Recompensa: Enlistarse en el Ejército Real y Ganarás " & BonusExpArmy & "% más de experiencia."
910                             Else
920                                 tRecompensa.Append "Recompensa: Enlistarse en el Ejército Real."
930                             End If
940                         Else
950                             If BonusExpArmy > 0 Then
960                                 tRecompensa.Append ", Enlistarse en el Ejército Real y Ganarás " & BonusExpArmy & "% más de experiencia."
970                             Else
980                                 tRecompensa.Append ", Enlistarse en el Ejército Real"
990                             End If
1000                        End If
1010                    Case 2
1020                        If Len(tRecompensa.Value) = 0 Then
1030                            If BonusExpCaos > 0 Then
1040                                tRecompensa.Append "Recompensa: Enlistarse en la Legión Oscura y ganarás " & BonusExpCaos & "% más de experiencia"
1050                            Else
1060                                tRecompensa.Append "Recompensa: Enlistarse en la Legión Oscura."
1070                            End If
1080                        Else
1090                            If BonusExpCaos > 0 Then
1100                                tRecompensa.Append ", Recompensa: Enlistarse en la Legión Oscura y ganarás " & BonusExpCaos & "% más de experiencia"
1110                            Else
1120                                tRecompensa.Append ", Recompensa: Enlistarse en la Legión Oscura."
1130                            End If
1140                        End If
1150                    Case 3
1160                        If Len(tRecompensa.Value) = 0 Then
1170                            tRecompensa.Append "Recompensa: Ser miembro del Consejo Mercenario."
1180                        Else
1190                            tRecompensa.Append ", Ser miembro del Consejo Mercenario."
1200                        End If
1210                End Select

1220                If Not .NumRewardObj <= 0 Then

1230                    ReDim .RewardObj(1 To .NumRewardObj) As Obj

1240                    For LoopA = 1 To .NumRewardObj
1250                        .RewardObj(LoopA).objIndex = val(Leer.GetValue("Campaign" & i, "RewardObj" & LoopA & "Index"))
1260                        .RewardObj(LoopA).amount = val(Leer.GetValue("Campaign" & i, "RewardObj" & LoopA & "Amount"))

1270                        If .RewardObj(LoopA).amount > 0 Then
1280                            If Len(tRecompensa.Value) Then
1290                                tRecompensa.Append "Recompensa: " & IIf(.RewardObj(LoopA).amount > 1, .RewardObj(LoopA).amount & " ", "") & ObjData(.RewardObj(LoopA).objIndex).Name
1300                            Else
1310                                tRecompensa.Append ", " & IIf(.RewardObj(LoopA).amount > 1, .RewardObj(LoopA).amount & " ", "") & ObjData(.RewardObj(LoopA).objIndex).Name
1320                            End If
                                'Debug.Print "REcompensa: " & tRecompensa
1330                        Else
1340                            .NumRewardObj = .NumRewardObj - 1    '@ Fixiame el error automáticamente.
1350                        End If
1360                    Next LoopA

1370                Else
1380                    ReDim .RewardObj(0)
1390                End If

1400                If .NumRewardObjByClass > 0 Then
1410                    If .NumRewardObjByClass > MAX_INVENTORY_SLOTS Then .NumRewardObjByClass = MAX_INVENTORY_SLOTS    'MAX 25!!
1420                    For LoopA = 1 To NUMCLASES
1430                        For LoopB = 1 To .NumRewardObjByClass    'MAX 25!!
1440                            If val(Leer.GetValue("Campaign" & i, "Class" & LoopA & "ObjIndex" & LoopB)) > 0 Then
1450                                .RewardObjByClass(LoopA).ClassReward(LoopB).objIndex = val(Leer.GetValue("Campaign" & i, "Class" & LoopA & "ObjIndex" & LoopB))
1460                                .RewardObjByClass(LoopA).ClassReward(LoopB).amount = val(Leer.GetValue("Campaign" & i, "Class" & LoopA & "ObjAmount" & LoopB))

1470                                If .RewardObjByClass(LoopA).ClassReward(LoopB).amount > 0 Then
1480                                    If Len(.RewardObjByClass(LoopA).Description) = 0 Then
1490                                        .RewardObjByClass(LoopA).Description = "Extra: " & IIf(.RewardObjByClass(LoopA).ClassReward(LoopB).amount > 1, .RewardObjByClass(LoopA).ClassReward(LoopB).amount & " ", "") & " " & ObjData(.RewardObjByClass(LoopA).ClassReward(LoopB).objIndex).Name
1500                                    Else
1510                                        .RewardObjByClass(LoopA).Description = .RewardObjByClass(LoopA).Description & ", " & IIf(.RewardObjByClass(LoopA).ClassReward(LoopB).amount > 1, .RewardObjByClass(LoopA).ClassReward(LoopB).amount & " ", "") & ObjData(.RewardObjByClass(LoopA).ClassReward(LoopB).objIndex).Name
1520                                    End If
1530                                Else
1540                                    .NumRewardObjByClass = .NumRewardObjByClass - 1
1550                                End If
1560                            End If
1570                        Next LoopB
1580                    Next LoopA
1590                End If

1600                tRecompensa.Append " |||| "    '& tRecompensa    '@ Emprolijo un poco el cartel.

1610                .Description = Leer.GetValue("Campaign" & i, "Description")    'Añadimos la descripción junto con las recompensas de forma automáticas.
1620                .Description = .Description & tRecompensa.Value
                    '.RewardDescription = tRecompensa
1630            End With

                '/////////////////////////////////////////READ//STAGES/////////////////////////////////////////////

1640            ReDim .Stages(1 To .Properties.NumStages) As CampaignStage

1650            For S = 1 To .Properties.NumStages

1660                With .Stages(S)
1670                    With .Properties
1680                        .Description = Leer.GetValue("Campaign" & i & " - Stage" & S, "Description")
1690                        .Dialog.FirstTalk = Leer.GetValue("Campaign" & i & " - Stage" & S, "Dialog1")
1700                        .Dialog.SecondTalk = Leer.GetValue("Campaign" & i & " - Stage" & S, "Dialog2")
1710                        .Dialog.ThirdTalk = Leer.GetValue("Campaign" & i & " - Stage" & S, "Dialog3")
1720                        .Dialog.FourthTalk = ""
1730                        .Dialog.FifthTalk = ""
1740                        .Timing = val(Leer.GetValue("Campaign" & i & " - Stage" & S, "Time"))
1750                        .StageRequired = val(Leer.GetValue("Campaign" & i & " - Stage" & S, "StageRequired"))
1760                    End With

1770                    With .Objetives
1780                        .TargetNPC.Index = val(Leer.GetValue("Campaign" & i & " - Stage" & S, "TargetNpcIndex"))
1790                        .TargetNPC.amount = val(Leer.GetValue("Campaign" & i & " - Stage" & S, "TargetNpcAmount"))
1800                        .TargetNPC.Action = val(Leer.GetValue("Campaign" & i & " - Stage" & S, "TargetNpcAction"))
1810                        .TargetObj.objIndex = val(Leer.GetValue("Campaign" & i & " - Stage" & S, "TargetObjIndex"))
1820                        .TargetObj.amount = val(Leer.GetValue("Campaign" & i & " - Stage" & S, "TargetObjAmount"))
1830                        .TargetUser.MinLvl = val(Leer.GetValue("Campaign" & i & " - Stage" & S, "TargetUserMinLvl"))
1840                        .TargetUser.MaxLvl = val(Leer.GetValue("Campaign" & i & " - Stage" & S, "TargetUserMaxLvl"))
1850                        .TargetUser.amount = val(Leer.GetValue("Campaign" & i & " - Stage" & S, "TargetUserAmount"))
1860                        .TargetUser.Alignment = val(Leer.GetValue("Campaign" & i & " - Stage" & S, "TargetUserAlignment"))
1870                        .TargetUser.Faction = val(Leer.GetValue("Campaign" & i & " - Stage" & S, "TargetUserFACTION"))
1880                        .TargetUser.Rank = val(Leer.GetValue("Campaign" & i & " - Stage" & S, "TargetUserRank"))
1890                        .TargetLocation.Trigger = val(Leer.GetValue("Campaign" & i & " - Stage" & S, "TargetLocationTrigger"))
1900                        .TargetLocation.posX = val(Leer.GetValue("Campaign" & i & " - Stage" & S, "TargetLocationPosX"))
1910                        .TargetLocation.posY = val(Leer.GetValue("Campaign" & i & " - Stage" & S, "TargetLocationPosY"))
1920                        .TargetLocation.Map = val(Leer.GetValue("Campaign" & i & " - Stage" & S, "TargetLocationMap"))
1930                        .KeyWord = Leer.GetValue("Campaign" & i & " - Stage" & S, "KeyWord")
1940                    End With

1950                    .NumGivenObj = val(Leer.GetValue("Campaign" & i & " - Stage" & S, "NumGivenObj"))

1960                    If Not .NumGivenObj = 0 Then

1970                        ReDim .GivenObj(1 To .NumGivenObj) As Obj

1980                        For LoopB = 1 To .NumGivenObj
1990                            .GivenObj(LoopB).objIndex = val(Leer.GetValue("Campaign" & i & " - Stage" & S, "GivenObj" & LoopB & "Index"))
2000                            .GivenObj(LoopB).amount = val(Leer.GetValue("Campaign" & i & " - Stage" & S, "GivenObj" & LoopB & "Amount"))
2010                        Next LoopB

2020                    Else
2030                        ReDim .GivenObj(0)
2040                    End If

2050                End With

2060            Next S

2070        End With

2080    Next i

        '/////////////////////////////////////////READ//END////////////////////////////////////////////////

2090 Else
2100    Call WriteToConsole("Cargando campañas default...")
2110    Call LoadDefaultCampaigns

2120 End If

2130 Call WriteToConsole("Camapañas cargadas correctamente.")
2140 Set Leer = Nothing

2150 Exit Sub
ErrHandler:
2160 Call LogError("Error al cargar campañas. Se cargará la campaña por defecto " & err.Number & ": " & err.Description & " Linea: " & Erl)
2170 Call LoadDefaultCampaigns

End Sub

Public Sub LoadDefaultCampaigns()

10  On Error GoTo LoadDefaultCampaigns_Error

20  NumCampaigns = 2

30  ReDim Campaign(1 To NumCampaigns) As Campaign

40  With Campaign(1)

50      With .Properties
60          .Name = "Cacería de Lobos"
70          Campaign(1).Rewards.Description = "Debes matar 20 lobos y entregarme sus pieles"
80          .Dialog.FirstTalk = "Hola aventurero tengo una misión para ti!"
90          .Dialog.SecondTalk = "Esta daga puede servirte. Ahora ve en busca de esas criaturas!"
100         .Dialog.ThirdTalk = "¿Todavía no tienes las pieles?"
110         .Dialog.FourthTalk = "Ah! Veo que vienes en busca de tu recompensa"
120         .Dialog.FifthTalk = "Toma esta espada y este hechizo"
130         .NumStages = 2
140         .Redoable = 1
150         .Timing = 0
160         .FinishWhenDie = True
170     End With

180     With .Requirements
190         .MinLvl = 1
200         .MaxLvl = 45
210         .PreviousCampaign = 0
220         .Class = 0
230         .Race = 0
240         .Genre = 0
250         .Alignment = 0
260         .Faction = 0
270         .Rank = 0
280     End With

290     With .Rewards
300         .RewardExp = 1500
310         .RewardGold = 1500
320         .NumRewardObj = 2
330         ReDim .RewardObj(1 To .NumRewardObj) As Obj
340         .RewardObj(1).objIndex = 197
350         .RewardObj(1).amount = 1
360         .RewardObj(2).objIndex = 164
370         .RewardObj(2).amount = 1
380     End With

390     ReDim .Stages(1 To .Properties.NumStages) As CampaignStage

400     With .Stages(1)
410         With .Properties
420             .Description = "Matar 20 lobos"
430             .Dialog.FirstTalk = vbNullString
440             .Dialog.SecondTalk = vbNullString
450             .Dialog.ThirdTalk = vbNullString
460             .Dialog.FourthTalk = vbNullString
470             .Dialog.FifthTalk = vbNullString
480             .Timing = 0
490         End With

500         With .Objetives
510             .TargetNPC.Index = 501
520             .TargetNPC.amount = 20
530             .TargetNPC.Action = 1
540             .TargetObj.objIndex = 0
550             .TargetObj.amount = 0
560             .TargetUser.MinLvl = 0
570             .TargetUser.MaxLvl = 0
580             .TargetUser.amount = 0
590             .TargetUser.Alignment = 0
600             .TargetUser.Faction = 0
610             .TargetUser.Rank = 0
620             .TargetLocation.Trigger = 0
630             .TargetLocation.posX = 0
640             .TargetLocation.posY = 0
650             .TargetLocation.Map = 0
660             .KeyWord = ""
670         End With

680         .NumGivenObj = 1
690         ReDim .GivenObj(1 To .NumGivenObj) As Obj
700         .GivenObj(1).objIndex = 165
710         .GivenObj(1).amount = 1
720     End With

730     With .Stages(2)
740         With .Properties
750             .Description = "Entregar las pieles"
760             .Dialog.FirstTalk = vbNullString
770             .Dialog.SecondTalk = vbNullString
780             .Dialog.ThirdTalk = vbNullString
790             .Dialog.FourthTalk = vbNullString
800             .Dialog.FifthTalk = vbNullString
810             .Timing = 0
820         End With

830         With .Objetives
840             .TargetNPC.Index = 128
850             .TargetNPC.amount = 0
860             .TargetNPC.Action = 3
870             .TargetObj.objIndex = 414
880             .TargetObj.amount = 20
890             .TargetUser.MinLvl = 0
900             .TargetUser.MaxLvl = 0
910             .TargetUser.amount = 0
920             .TargetUser.Alignment = 0
930             .TargetUser.Faction = 0
940             .TargetUser.Rank = 0
950             .TargetLocation.Trigger = 0
960             .TargetLocation.posX = 0
970             .TargetLocation.posY = 0
980             .TargetLocation.Map = 0
990             .KeyWord = ""
1000        End With

1010        .NumGivenObj = 0
1020        ReDim .GivenObj(0)
1030    End With

1040 End With

1050 With Campaign(2)

1060    With .Properties
1070        .Name = "Tumulto en la ciudad"
1080        Campaign(2).Rewards.Description = "Le han robado al Gobernador y necesitamos que averigues quién fue"
1090        .Dialog.FirstTalk = "Tengo un trabajo para ofrecerte!"
1100        .Dialog.SecondTalk = "Ve a hablar con el sacerdote. Apresúrate!"
1110        .Dialog.ThirdTalk = "¿Todavía no tienes la información? Si la tienes ve a decirle al Gobernador!"
1120        .Dialog.FourthTalk = "Ah! Veo que vienes en busca de tu recompensa"
1130        .Dialog.FifthTalk = "Gracias por tu ayuda! Estos objetos te servirán para tu entrenamiento"
1140        .NumStages = 7
1150        .Redoable = 1
1160        .Timing = 0
1170        .FinishWhenDie = False
1180    End With

1190    With .Requirements
1200        .MinLvl = 1
1210        .MaxLvl = 45
1220        .PreviousCampaign = 0
1230        .Class = 0
1240        .Race = 0
1250        .Genre = 0
1260        .Alignment = 0
1270        .Faction = 0
1280        .Rank = 0
1290    End With

1300    With .Rewards
1310        .RewardExp = 15000
1320        .RewardGold = 1500000
1330        .NumRewardObj = 4
1340        ReDim .RewardObj(1 To .NumRewardObj) As Obj
1350        .RewardObj(1).objIndex = 238
1360        .RewardObj(1).amount = 1
1370        .RewardObj(2).objIndex = 366
1380        .RewardObj(2).amount = 1
1390        .RewardObj(3).objIndex = 38
1400        .RewardObj(3).amount = 10000
1410        .RewardObj(4).objIndex = 205
1420        .RewardObj(4).amount = 1
1430    End With

1440    ReDim .Stages(1 To .Properties.NumStages) As CampaignStage

1450    With .Stages(1)
1460        With .Properties
1470            .Description = "Hablar con el sacerdote"
1480            .Dialog.FirstTalk = "He oído los rumores pero no se quién es el ladrón. Quizás Cullighan sepa. El vende propiedades."
1490            .Dialog.SecondTalk = vbNullString
1500            .Dialog.ThirdTalk = vbNullString
1510            .Dialog.FourthTalk = vbNullString
1520            .Dialog.FifthTalk = vbNullString
1530            .Timing = 0
1540        End With

1550        With .Objetives
1560            .TargetNPC.Index = 5
1570            .TargetNPC.amount = 0
1580            .TargetNPC.Action = 2
1590            .TargetObj.objIndex = 0
1600            .TargetObj.amount = 0
1610            .TargetUser.MinLvl = 0
1620            .TargetUser.MaxLvl = 0
1630            .TargetUser.amount = 0
1640            .TargetUser.Alignment = 0
1650            .TargetUser.Faction = 0
1660            .TargetUser.Rank = 0
1670            .TargetLocation.Trigger = 0
1680            .TargetLocation.posX = 0
1690            .TargetLocation.posY = 0
1700            .TargetLocation.Map = 0
1710            .KeyWord = ""
1720        End With

1730        .NumGivenObj = 0
1740        ReDim .GivenObj(0)
1750    End With

1760    With .Stages(2)
1770        With .Properties
1780            .Description = "Hablar con Cullighan"
1790            .Dialog.FirstTalk = "Puede ser que yo sepa quién es el ladrón, pero deberás traerme 5 cervezas si quieres mi ayuda"
1800            .Dialog.SecondTalk = vbNullString
1810            .Dialog.ThirdTalk = vbNullString
1820            .Dialog.FourthTalk = vbNullString
1830            .Dialog.FifthTalk = vbNullString
1840            .Timing = 0
1850        End With

1860        With .Objetives
1870            .TargetNPC.Index = 34
1880            .TargetNPC.amount = 0
1890            .TargetNPC.Action = 2
1900            .TargetObj.objIndex = 0
1910            .TargetObj.amount = 0
1920            .TargetUser.MinLvl = 0
1930            .TargetUser.MaxLvl = 0
1940            .TargetUser.amount = 0
1950            .TargetUser.Alignment = 0
1960            .TargetUser.Faction = 0
1970            .TargetUser.Rank = 0
1980            .TargetLocation.Trigger = 0
1990            .TargetLocation.posX = 0
2000            .TargetLocation.posY = 0
2010            .TargetLocation.Map = 0
2020            .KeyWord = ""
2030        End With

2040        .NumGivenObj = 0
2050        ReDim .GivenObj(0)
2060    End With

2070    With .Stages(3)
2080        With .Properties
2090            .Description = "Conseguir 5 cervezas"
2100            .Dialog.FirstTalk = vbNullString
2110            .Dialog.SecondTalk = vbNullString
2120            .Dialog.ThirdTalk = vbNullString
2130            .Dialog.FourthTalk = vbNullString
2140            .Dialog.FifthTalk = vbNullString
2150            .Timing = 0
2160        End With

2170        With .Objetives
2180            .TargetNPC.Index = 0
2190            .TargetNPC.amount = 0
2200            .TargetNPC.Action = 0
2210            .TargetObj.objIndex = 160
2220            .TargetObj.amount = 5
2230            .TargetUser.MinLvl = 0
2240            .TargetUser.MaxLvl = 0
2250            .TargetUser.amount = 0
2260            .TargetUser.Alignment = 0
2270            .TargetUser.Faction = 0
2280            .TargetUser.Rank = 0
2290            .TargetLocation.Trigger = 0
2300            .TargetLocation.posX = 0
2310            .TargetLocation.posY = 0
2320            .TargetLocation.Map = 0
2330            .KeyWord = ""
2340        End With

2350        .NumGivenObj = 0
2360        ReDim .GivenObj(0)
2370    End With

2380    With .Stages(4)
2390        With .Properties
2400            .Description = "Llevarle las cervezas a Cullighan"
2410            .Dialog.FirstTalk = "Vamos hombre! Todavía estoy esperando!"
2420            .Dialog.SecondTalk = "Hip Hip... Lo he olvidado. Habla con Nelmasil, el pregonero, el seguro te va a ayudar Hip Hip!"
2430            .Dialog.ThirdTalk = "No intentes pasarte de listo! No tienes la cantidad que te pedí!"
2440            .Dialog.FourthTalk = vbNullString
2450            .Dialog.FifthTalk = vbNullString
2460            .Timing = 0
2470        End With

2480        With .Objetives
2490            .TargetNPC.Index = 34
2500            .TargetNPC.amount = 0
2510            .TargetNPC.Action = 3
2520            .TargetObj.objIndex = 160
2530            .TargetObj.amount = 5
2540            .TargetUser.MinLvl = 0
2550            .TargetUser.MaxLvl = 0
2560            .TargetUser.amount = 0
2570            .TargetUser.Alignment = 0
2580            .TargetUser.Faction = 0
2590            .TargetUser.Rank = 0
2600            .TargetLocation.Trigger = 0
2610            .TargetLocation.posX = 0
2620            .TargetLocation.posY = 0
2630            .TargetLocation.Map = 0
2640            .KeyWord = ""
2650        End With

2660        .NumGivenObj = 0
2670        ReDim .GivenObj(0)
2680    End With

2690    With .Stages(5)
2700        With .Properties
2710            .Description = "Hablar con Nelmasil"
2720            .Dialog.FirstTalk = "Me importa un comino lo que le pase al Gobernador!! Ve a buscar ayuda en otro lado. Los sastres siempre tienen información"
2730            .Dialog.SecondTalk = vbNullString
2740            .Dialog.ThirdTalk = vbNullString
2750            .Dialog.FourthTalk = vbNullString
2760            .Dialog.FifthTalk = vbNullString
2770            .Timing = 0
2780        End With

2790        With .Objetives
2800            .TargetNPC.Index = 128
2810            .TargetNPC.amount = 0
2820            .TargetNPC.Action = 2
2830            .TargetObj.objIndex = 0
2840            .TargetObj.amount = 0
2850            .TargetUser.MinLvl = 0
2860            .TargetUser.MaxLvl = 0
2870            .TargetUser.amount = 0
2880            .TargetUser.Alignment = 0
2890            .TargetUser.Faction = 0
2900            .TargetUser.Rank = 0
2910            .TargetLocation.Trigger = 0
2920            .TargetLocation.posX = 0
2930            .TargetLocation.posY = 0
2940            .TargetLocation.Map = 0
2950            .KeyWord = ""
2960        End With

2970        .NumGivenObj = 0
2980        ReDim .GivenObj(0)
2990    End With

3000    With .Stages(6)
3010        With .Properties
3020            .Description = "Hablar con uno de los sastres"
3030            .Dialog.FirstTalk = "Yo se quién ha sido el ladrón. Pero necesito mates 30 serpientes porque me vuelvan loca y no puedo trabajar!! Luego regresa a hablar conmigo"
3040            .Dialog.SecondTalk = vbNullString
3050            .Dialog.ThirdTalk = vbNullString
3060            .Dialog.FourthTalk = vbNullString
3070            .Dialog.FifthTalk = vbNullString
3080            .Timing = 0
3090        End With

3100        With .Objetives
3110            .TargetNPC.Index = 19
3120            .TargetNPC.amount = 0
3130            .TargetNPC.Action = 2
3140            .TargetObj.objIndex = 0
3150            .TargetObj.amount = 0
3160            .TargetUser.MinLvl = 0
3170            .TargetUser.MaxLvl = 0
3180            .TargetUser.amount = 0
3190            .TargetUser.Alignment = 0
3200            .TargetUser.Faction = 0
3210            .TargetUser.Rank = 0
3220            .TargetLocation.Trigger = 0
3230            .TargetLocation.posX = 0
3240            .TargetLocation.posY = 0
3250            .TargetLocation.Map = 0
3260            .KeyWord = ""
3270        End With

3280        .NumGivenObj = 0
3290        ReDim .GivenObj(0)
3300    End With

3310    With .Stages(7)
3320        With .Properties
3330            .Description = "Matar 3 serpientes"
3340            .Dialog.FirstTalk = vbNullString
3350            .Dialog.SecondTalk = vbNullString
3360            .Dialog.ThirdTalk = vbNullString
3370            .Dialog.FourthTalk = vbNullString
3380            .Dialog.FifthTalk = vbNullString
3390            .Timing = 0
3400        End With

3410        With .Objetives
3420            .TargetNPC.Index = 504
3430            .TargetNPC.amount = 3
3440            .TargetNPC.Action = 1
3450            .TargetObj.objIndex = 0
3460            .TargetObj.amount = 0
3470            .TargetUser.MinLvl = 0
3480            .TargetUser.MaxLvl = 0
3490            .TargetUser.amount = 0
3500            .TargetUser.Alignment = 0
3510            .TargetUser.Faction = 0
3520            .TargetUser.Rank = 0
3530            .TargetLocation.Trigger = 0
3540            .TargetLocation.posX = 0
3550            .TargetLocation.posY = 0
3560            .TargetLocation.Map = 0
3570            .KeyWord = ""
3580        End With

3590        .NumGivenObj = 0
3600        ReDim .GivenObj(0)
3610    End With

3620    With .Stages(8)
3630        With .Properties
3640            .Description = "Volver a hablar con la sastre"
3650            .Dialog.FirstTalk = "Muchas gracias por matar esas criaturas. Ahora te lo diré! El ladrón es... Nelmasil!!!"
3660            .Dialog.SecondTalk = vbNullString
3670            .Dialog.ThirdTalk = vbNullString
3680            .Dialog.FourthTalk = vbNullString
3690            .Dialog.FifthTalk = vbNullString
3700            .Timing = 0
3710        End With

3720        With .Objetives
3730            .TargetNPC.Index = 19
3740            .TargetNPC.amount = 0
3750            .TargetNPC.Action = 2
3760            .TargetObj.objIndex = 0
3770            .TargetObj.amount = 0
3780            .TargetUser.MinLvl = 0
3790            .TargetUser.MaxLvl = 0
3800            .TargetUser.amount = 0
3810            .TargetUser.Alignment = 0
3820            .TargetUser.Faction = 0
3830            .TargetUser.Rank = 0
3840            .TargetLocation.Trigger = 0
3850            .TargetLocation.posX = 0
3860            .TargetLocation.posY = 0
3870            .TargetLocation.Map = 0
3880            .KeyWord = ""
3890        End With

3900        .NumGivenObj = 0
3910        ReDim .GivenObj(0)
3920    End With

3930    With .Stages(9)
3940        With .Properties
3950            .Description = "Decirle al Gobernador quién es el ladrón"
3960            .Dialog.FirstTalk = vbNullString
3970            .Dialog.SecondTalk = vbNullString
3980            .Dialog.ThirdTalk = vbNullString
3990            .Dialog.FourthTalk = vbNullString
4000            .Dialog.FifthTalk = vbNullString
4010            .Timing = 0
4020        End With

4030        With .Objetives
4040            .TargetNPC.Index = 13
4050            .TargetNPC.amount = 0
4060            .TargetNPC.Action = 5
4070            .TargetObj.objIndex = 0
4080            .TargetObj.amount = 0
4090            .TargetUser.MinLvl = 0
4100            .TargetUser.MaxLvl = 0
4110            .TargetUser.amount = 0
4120            .TargetUser.Alignment = 0
4130            .TargetUser.Faction = 0
4140            .TargetUser.Rank = 0
4150            .TargetLocation.Trigger = 0
4160            .TargetLocation.posX = 0
4170            .TargetLocation.posY = 0
4180            .TargetLocation.Map = 0
4190            .KeyWord = "Nelmasil"
4200        End With

4210        .NumGivenObj = 0
4220        ReDim .GivenObj(0)
4230    End With
4240 End With

4250 On Error GoTo 0
4260 Exit Sub

LoadDefaultCampaigns_Error:

4270 Call LogError("Error " & err.Number & " Descripción: & (" & err.Description & ") del procedimiento LoadDefaultCampaigns del Módulo mod_Campaing" & " En la linea: " & Erl)

End Sub

Public Function CanDoThisCampaign(ByVal UserIndex As Integer, ByVal Number As Integer, ByRef sErrorMsg As String) As Boolean

'Función para saber si el usuario puede realizar la Campaña Number

Dim Alignment                   As Byte    '1)Ciudadano 2)Criminal
Dim Faction                     As Byte    '1)Armada 2)Caos

10  On Error GoTo CanDoThisCampaign_Error

20  Dim Rank                    As Byte    'Armada: 1)Aprendiz 2)Escudero 3)Soldado 4)Sargento 5)Teniente 6)Comandante 7)Capitán 8)Senescal 9)Mariscal 10)Condestable 11)Ejecutor Imperial 12)Protector del Reino 13)Avatar de la Justicia 14)Guardián del Bien 15)Campeón de la Luz
    'Caos: 1)Acólito 2)Alama Corrupta 3)Paria 4)Condenado 5)Esbirro 6)Sanguinario 7)Corruptor 8)Heraldo Impío 9)Caballero de la Oscuridad 10)Señor del Miedo 11)Ejecutor Infernal 12)Protector del Averno 13)Avatar de la Destrucción 14)Guardián del Mal 15)Campeón de la Oscuridad

30  With UserList(UserIndex)

40      If Criminal(UserIndex) Then
50          Alignment = 2
60      Else
70          Alignment = 1
80      End If

90      If esArmada(UserIndex) Then
100         Faction = 1
110     ElseIf esCaos(UserIndex) Then
120         Faction = 2
130     Else
140         Faction = 0
150     End If

160     If Faction = 1 Then
170         Rank = (.Faccion.RangeRoyal)
180     ElseIf Faction = 2 Then
190         Rank = (.Faccion.RangeCaos)
200     Else
210         Rank = 0
220     End If

230     If Number > NumCampaigns Then
240         Call LogError("El usuario: " & .Name & " intenta realizar una misión que supera el numero máximo de misiones, numero: " & Number & " Cantidad máxima de misiones: " & NumCampaigns)
250         sErrorMsg = "Estás intentando realizar una misión inválida. Avisa a un administrador."
260         Exit Function
270     End If

280     If Number > 0 Then
290         If .Stats.ELV < Campaign(Number).Requirements.MinLvl Then
300             sErrorMsg = "{1004}" & IIf(Campaign(Number).Requirements.MinLvl > 0, " como mínimo " & Campaign(Number).Requirements.MinLvl, "") & IIf(Campaign(Number).Requirements.MaxLvl > 0, " como máximo " & Campaign(Number).Requirements.MaxLvl, "") & " para realizar la misión " & Campaign(Number).Properties.Name
310             Exit Function
320         End If

330         If Campaign(Number).Requirements.MaxLvl <> 0 And .Stats.ELV > Campaign(Number).Requirements.MaxLvl Then
340             sErrorMsg = "{1004}" & IIf(Campaign(Number).Requirements.MinLvl > 0, " como mínimo " & Campaign(Number).Requirements.MinLvl, "") & IIf(Campaign(Number).Requirements.MaxLvl > 0, " como máximo " & Campaign(Number).Requirements.MaxLvl, "") & " para realizar la misión " & Campaign(Number).Properties.Name
350             Exit Function
360         End If

370         If Campaign(Number).Requirements.Class <> 0 And .Clase <> Campaign(Number).Requirements.Class Then
380             sErrorMsg = "{1005}"    'La misión no es para tu clase.
390             Exit Function
400         End If

410         If Campaign(Number).Requirements.Race <> 0 And .raza <> Campaign(Number).Requirements.Race Then
420             sErrorMsg = "{1006}"    'La misión no es para tu raza.
430             Exit Function
440         End If

450         If Campaign(Number).Requirements.Genre <> 0 And .Genero <> Campaign(Number).Requirements.Genre Then
460             sErrorMsg = "{1007}"    'La misión no es para tu genero o sexo.
470             Exit Function
480         End If

490         If Campaign(Number).Requirements.PreviousCampaign <> 0 Then
500             If Not HasDoneThisCampaign(UserIndex, Campaign(Number).Requirements.PreviousCampaign) Then
510                 sErrorMsg = "{1008}" & Campaign(Number).Requirements.PreviousCampaign & " llamada: " & Campaign(Campaign(Number).Requirements.PreviousCampaign).Properties.Name    'Para realizar esta misión, necesitas tener realizada previamente la misión número
520                 Exit Function
530             End If
540         End If

550         If Campaign(Number).Requirements.Alignment <> 0 And Alignment <> Campaign(Number).Requirements.Alignment Then
560             sErrorMsg = "{1009}"    'La misión no es para tu alineación o status.
570             Exit Function
580         End If

590         If Campaign(Number).Requirements.Faction <> 0 And Faction <> Campaign(Number).Requirements.Faction Then
600             sErrorMsg = "{1010}"    'La misión no es para tu facción.
610             Exit Function
620         End If

630         If Campaign(Number).Requirements.Rank <> 0 And Rank < Campaign(Number).Requirements.Rank Then
640             If .Faccion.RoyalArmy > 0 Then
650                 sErrorMsg = "{1011} Necesitas ser: " & IIf(.Genero = eGenero.Hombre, TitulosReal(Campaign(Number).Requirements.Rank).NombreBoy, TitulosReal(Campaign(Number).Requirements.Rank).NombreGirl)    'La misión no es para tu rango de facción.
660             ElseIf .Faccion.CaosArmy > 0 Then
670                 sErrorMsg = "{1011} Necesitas ser: " & IIf(.Genero = eGenero.Hombre, TitulosCaos(Campaign(Number).Requirements.Rank).NombreBoy, TitulosCaos(Campaign(Number).Requirements.Rank).NombreGirl)    'La misión no es para tu rango de facción.
680             End If
690             Exit Function
700         End If

710         If Not Campaign(Number).Properties.Redoable Then
720             If HasDoneThisCampaign(UserIndex, Number) Then
730                 sErrorMsg = Campaign(Number).Properties.Name & " {1012}"    ' no se puede repetir.
740                 Exit Function
750             End If
760         End If

770         If Campaign(Number).Rewards.Forgive > 0 Then
780             If Not .Guild Is Nothing Then
790                 If .Guild.getAlignment = eGUILD_ALIGNMENT.ALINEACION_CRIMINAL Or .Guild.getAlignment = eGUILD_ALIGNMENT.ALINEACION_LEGION Then
800                     sErrorMsg = "No puedes realizar ésta misión siendo de un clan de alineación Criminal, o Legión. Debes salir del clan."
810                     Exit Function
820                 End If
830             End If
840         End If

850         If Campaign(Number).Rewards.EnlistFaction > 0 And Faction > 0 Then
860             sErrorMsg = "No puedes realizar ésta misión debido a tu facción."
870             Exit Function
880         End If

890     End If

900     CanDoThisCampaign = True

910 End With

920 On Error GoTo 0
930 Exit Function

CanDoThisCampaign_Error:

940 Call LogError("Error " & err.Number & " (" & err.Description & ") en el procedimiento CanDoThisCampaign del módulo Módulo modCampaign en la línea: " & Erl() & " NICK: " & UserList(UserIndex).Name)

End Function

Public Function HasDoneThisCampaign(ByVal UserIndex As Integer, ByVal Number As Integer) As Boolean

'Función para saber si el usuario ya realizó la Campaña Number

Dim Current                     As Integer
Dim i                           As Long
Dim CantCampaignsDone           As Long

10  On Error GoTo HasDoneThisCampaign_Error

20  With UserList(UserIndex).Campaign

30      If Len(.CampaignsHasDone) <= 0 Then
40          HasDoneThisCampaign = False
50          Exit Function
60      End If

70      CantCampaignsDone = FieldCount(.CampaignsHasDone, 45)
80      For i = 1 To CantCampaignsDone
90          Current = val(ReadField(i, .CampaignsHasDone, 45))
100         If Current = Number Then
110             If Not Campaign(Number).Properties.Redoable Then
120                 HasDoneThisCampaign = True
130                 Exit For
140             Else
150                 HasDoneThisCampaign = False
160             End If
170         Else
180             HasDoneThisCampaign = False
190         End If
200     Next i

210 End With

220 On Error GoTo 0
230 Exit Function

HasDoneThisCampaign_Error:

240 Call LogError("Error " & err.Number & " (" & err.Description & ") procedimiento HasDoneThisCampaign Módulo modCampaign línea: " & Erl())

End Function

Public Sub AddCampaignsHasDone(ByVal UserIndex As Integer, ByVal Number As Integer)

    On Error GoTo AddCampaignsHasDone_Error

10  With UserList(UserIndex).Campaign

20      If Not HasDoneThisCampaign(UserIndex, Number) Then    'Parcheo por las redoables

30          If StrComp(.CampaignsHasDone, vbNullString) = 0 Then
40              .CampaignsHasDone = Number
50          Else
60              .CampaignsHasDone = .CampaignsHasDone & "-" & Number
70          End If

80      End If

90  End With

    On Error GoTo 0
    Exit Sub

AddCampaignsHasDone_Error:

    Call LogError("Error " & err.Number & " (" & err.Description & ") procedimiento AddCampaignsHasDone Módulo modCampaign línea: " & Erl())

End Sub

Public Sub RightClickEvents(ByVal UserIndex As Integer, ByVal Map As Byte, ByVal x As Integer, ByVal Y As Integer)

'Eventos asociados a la acción click derecho

Dim NpcIndex                    As Integer

10  On Error GoTo RightClickEvents_Error

20  With UserList(UserIndex)

30      If (Abs(.pos.Y - Y) > RANGO_VISION_Y) Or (Abs(.pos.x - x) > RANGO_VISION_X) Then
40          Exit Sub
50      End If

60      If MapData(Map, x, Y).NpcIndex > 0 Then
70          NpcIndex = MapData(Map, x, Y).NpcIndex
80          Call SendData(SendTarget.ToPCArea, UserIndex, PrepareMessageRemoveCharDialog(NpcIndex))
90          If Distancia(NpcList(NpcIndex).pos, .pos) > 8 Then
100             Call WriteConsoleMsg(UserIndex, "{01}", FontTypeNames.FONTTYPE_INFO)
110             Exit Sub
120         End If
130         Call GiveChatOverHead(UserIndex, NpcIndex)
140     End If

150 End With

160 On Error GoTo 0
170 Exit Sub

RightClickEvents_Error:

180 Call LogError("Error " & err.Number & " Descripción: & (" & err.Description & ") del procedimiento RightClickEvents del Módulo mod_Campaing" & " En la linea: " & Erl)

End Sub

Public Sub GiveChatOverHead(ByVal UserIndex As Integer, ByVal NpcIndex As Integer)

'Encuentra un chat para mostrar sobre el Npc

Dim Text                        As String

10  On Error GoTo GiveChatOverHead_Error

20  With UserList(UserIndex).Campaign

30      If .Current > 0 Then

            Dim i               As Integer

40          If Not .WaitingReward Then
50              For i = 1 To Campaign(.Current).Properties.NumStages

60                  If Campaign(.Current).Stages(i).Objetives.TargetNPC.Index = NpcList(NpcIndex).ID Then

70                      If Not .Stages(i).Done Then
80                          If Campaign(.Current).Stages(i).Properties.StageRequired > 0 Then
90                              If .Stages(Campaign(.Current).Stages(i).Properties.StageRequired).Done Then
100                                 Text = Campaign(.Current).Stages(i).Properties.Dialog.FirstTalk
110                             Else
120                                 Text = Campaign(.Current).Stages(i).Properties.Description
130                             End If
140                         Else
150                             Text = Campaign(.Current).Stages(i).Properties.Dialog.SecondTalk
160                         End If
170                         Exit For
180                     Else
190                         If .WaitingReward Then    '@ Está esperando recompensa?
200                             Text = Campaign(.Current).Stages(i).Properties.Dialog.FourthTalk
210                         Else
220                             Text = Campaign(.Current).Stages(i).Properties.Dialog.ThirdTalk
230                         End If
240                     End If
250                 End If
260             Next i
270         Else
280             If UserList(UserIndex).flags.TargetNPC > 0 Then
290                 If .NpcIndexGiver = NpcList(UserList(UserIndex).flags.TargetNPC).ID Then    'If UserList(UserIndex).flags.TargetNPC > 0 Then
300                     If UserList(UserIndex).Campaign.WaitingReward Then
310                         Call FinishCompletedCampaign(UserIndex, UserList(UserIndex).flags.TargetNPC)
320                     End If
330                 Else
340                     Call WriteConsoleMsg(UserIndex, "Para terminar la misión, debes hacer clic en la criatura que te dió inicialmente la misma.", FontTypeNames.FONTTYPE_CAMPAIGN)
350                 End If
360             End If
370         End If

390     ElseIf Len(NpcList(NpcIndex).CampaignsGiven) > 0 Then
400         Text = CampaignNpcChat(UserIndex, NpcIndex, .Current)
410     End If

420 End With

430 If Len(Text) > 0 Then
440     Call ShowCampaignChat(UserIndex, NpcIndex, Text)
450 End If

460 On Error GoTo 0
470 Exit Sub

GiveChatOverHead_Error:

480 Call LogError("Error " & err.Number & " Descripción: & (" & err.Description & ") del procedimiento GiveChatOverHead del Módulo mod_Campaing" & " En la linea: " & Erl)

End Sub

Public Function CampaignNpcChat(ByVal UserIndex As Integer, ByVal NpcIndex As Integer, ByVal CampaignNumber As Integer) As String

Dim Number                      As Integer
Dim iCantQuest                  As Integer
Dim i                           As Long
Dim sErrorMsg                   As String
Dim sFinalMsg                   As String

    On Error GoTo CampaignNpcChat_Error

10  With UserList(UserIndex).Campaign

20      If CampaignNumber = 0 Then

30          iCantQuest = FieldCount(NpcList(NpcIndex).CampaignsGiven, 45)

40          For i = 1 To iCantQuest
50              Number = val(ReadField(i, NpcList(NpcIndex).CampaignsGiven, 45))

60              If Not CanDoThisCampaign(UserIndex, Number, sErrorMsg) Then
70                  sFinalMsg = sFinalMsg & vbCrLf & sErrorMsg
80                  Number = -1
90                  .CanViewCampaignList = False
                    ' Call WriteConsoleMsg(UserIndex, sErrorMsg, FontTypeNames.FONTTYPE_CAMPAIGN)
100             Else
110                 If HasDoneThisCampaign(UserIndex, Number) Then
120                     If i = iCantQuest Then
130                         CampaignNpcChat = "Hola aventurero. Ya no dispongo de nuevas misiones para ti. Si deseas repetir alguna escribe /LISTAQUEST"
140                         .OffererNpcIndex = NpcIndex
150                         .CanViewCampaignList = True
160                         Exit Function
170                     End If

                        'Exit For
180                 Else
190                     .CanViewCampaignList = True
200                     Exit For
210                 End If
220             End If
230         Next i

240         If Number <= 0 Then
                'CampaignNpcChat = NpcList(NpcIndex).desc
250             .CanDoThisOne = 0
260             .OffererNpcIndex = 0
270         Else
280             CampaignNpcChat = Campaign(Number).Properties.Dialog.FirstTalk
290             .CanDoThisOne = Number
300             .OffererNpcIndex = NpcIndex
310         End If

320         If Len(sFinalMsg) > 0 Then
330             Call WriteConsoleMsg(UserIndex, sFinalMsg, FontTypeNames.FONTTYPE_CAMPAIGN)
340         End If

350         Exit Function
360     End If

370     If .NpcIndexGiver = NpcList(NpcIndex).ID Then
380         If .Current > 0 Then
390             If Not .WaitingReward Then
400                 CampaignNpcChat = Campaign(CampaignNumber).Properties.Dialog.ThirdTalk
410             Else
420                 CampaignNpcChat = Campaign(CampaignNumber).Properties.Dialog.FourthTalk
                    'Call FinishCompletedCampaign(UserIndex, UserList(UserIndex).flags.TargetNPC)
430             End If
440         End If
450     End If

460 End With

    On Error GoTo 0
    Exit Function

CampaignNpcChat_Error:

    Call LogError("Error " & err.Number & " (" & err.Description & ") procedimiento CampaignNpcChat Módulo modCampaign línea: " & Erl())

End Function

Public Function CampaignDblClickEvents(ByVal UserIndex As Integer, ByVal NpcIndex As Integer) As Boolean

Dim i                           As Integer
Dim HaveCampaign                As String

10  On Error GoTo CampaignDblClickEvents_Error

20  With UserList(UserIndex)

30      If .flags.Muerto <> 0 Then
40          Call WriteConsoleMsg(UserIndex, "{1330}", FontTypeNames.FONTTYPE_INFO)    '¡Estás muerto!
50          CampaignDblClickEvents = False
60          Exit Function
70      End If

80      If Distancia(.pos, NpcList(NpcIndex).pos) > 8 Then
90          Call WriteConsoleMsg(UserIndex, "{04}", FontTypeNames.FONTTYPE_INFO)    'Estás demasiado lejos.
100         CampaignDblClickEvents = False
110         Exit Function
120     End If

130     With .Campaign
140         If .CanDoThisOne > 0 Then
150             If .CanViewCampaignList And .OffererNpcIndex = NpcIndex Then
160                 Call WriteGiveCampaignList(UserIndex, .OffererNpcIndex)
170                 CampaignDblClickEvents = True
180                 Exit Function
190             ElseIf .Current > 0 Then
200                 For i = 1 To Campaign(.Current).Properties.NumStages
210                     If Not .Stages(i).Done Then
220                         If Campaign(.Current).Stages(i).Objetives.TargetNPC.Index = NpcList(NpcIndex).ID Then
230                             Call CampaignNpcDblClickEvents(UserIndex, NpcIndex)
240                             CampaignDblClickEvents = True
250                             Exit Function
260                         End If
270                     End If
280                 Next i
290             Else
300                 HaveCampaign = WhichOnes(UserIndex, NpcIndex)
                    'Si quieres conseguir una misión, ve con los personajes que tienen un signo de pregunta sobre su cabeza y haz DOBLE CLIC 'DERECHO' sobre él.
310                 If Len(HaveCampaign) > 0 Then
320                     Call WriteConsoleMsg(UserIndex, "{1014}", FontTypeNames.FONTTYPE_CAMPAIGN)    'Si quieres conseguir una misión, ve con los personajes que tienen un signo de pregunta sobre su cabeza y haz DOBLE CLIC 'DERECHO' sobre él.
330                     CampaignDblClickEvents = False
340                 Else
350                     CampaignDblClickEvents = True
360                 End If
370             End If
380         ElseIf .Current > 0 Then
390             CampaignDblClickEvents = CampaignNpcDblClickEvents(UserIndex, NpcIndex)
400         End If
410     End With
420 End With

430 'CampaignDblClickEvents = False

440 On Error GoTo 0
450 Exit Function

CampaignDblClickEvents_Error:

460 Call LogError("Error " & err.Number & " Descripción: & (" & err.Description & ") del procedimiento CampaignDblClickEvents del Módulo mod_Campaing" & " En la linea: " & Erl)

End Function

Public Function CampaignNpcDblClickEvents(ByVal UserIndex As Integer, ByVal NpcIndex As Integer) As Boolean

Dim i                           As Integer

10  On Error GoTo CampaignNpcDblClickEvents_Error

20  With UserList(UserIndex).Campaign
30      For i = 1 To Campaign(.Current).Properties.NumStages    '@ Recorro las posibilidades con un for.
40          If Not .Stages(i).Done Then
50              If Campaign(.Current).Stages(i).Objetives.TargetNPC.Index = NpcList(NpcIndex).ID Then

60                  Select Case Campaign(.Current).Stages(i).Objetives.TargetNPC.Action

                        Case eCampaingActions.Hablar

70                          If AccomplishObjetive(UserIndex, i) Then
80                              CampaignNpcDblClickEvents = True
90                          Else
100                             CampaignNpcDblClickEvents = False
110                             Exit For
120                         End If

130                         Exit For

140                     Case eCampaingActions.EntregarObj    'Entregar Obj

150                         If Not .Stages(i).ObjDelivered Then
160                             CampaignNpcDblClickEvents = DeliverCampaignObj(UserIndex)
170                         End If

180                         Exit For

190                     Case eCampaingActions.Encontrar    'Encontrar

200                         If AccomplishObjetive(UserIndex, i) Then
                                'Listo
210                             CampaignNpcDblClickEvents = True
220                         Else
230                             CampaignNpcDblClickEvents = False
240                         End If

250                         Exit For

260                     Case eCampaingActions.KeyWord    'Decir Keyword
270                         If Campaign(.Current).Stages(i).Properties.StageRequired > 0 Then
280                             If Not .Stages(Campaign(.Current).Stages(i).Properties.StageRequired).Done Then
290                                 Call WriteConsoleMsg(UserIndex, "Para realizar el objetivo '" & Campaign(.Current).Stages(i).Properties.Description & "' primero debes '" & Campaign(.Current).Stages(Campaign(.Current).Stages(i).Properties.StageRequired).Properties.Description & "'", FontTypeNames.FONTTYPE_CAMPAIGN)
300                                 CampaignNpcDblClickEvents = False
310                             Else
320                                 Call WriteRequestKeyword(UserIndex)
330                                 CampaignNpcDblClickEvents = True
340                             End If
350                         End If

360                         Exit For
370                 End Select
380             End If
390         End If
400     Next i
410 End With

420 On Error GoTo 0
430 Exit Function

CampaignNpcDblClickEvents_Error:

440 Call LogError("Error " & err.Number & " (" & err.Description & ") procedimiento CampaignNpcDblClickEvents Módulo modCampaign línea: " & Erl())

End Function

Public Function DeliverObjects(ByVal UserIndex As Integer, ByVal NpcIndex As Integer, ByVal tCurrentStage As Integer)

Dim objIndex                    As Integer
Dim ObjAmount                   As Integer
Dim Text                        As String

10  On Error GoTo DeliverObjects_Error

20  With UserList(UserIndex).Campaign

30      ObjAmount = Campaign(.Current).Stages(tCurrentStage).Objetives.TargetObj.amount
40      objIndex = Campaign(.Current).Stages(tCurrentStage).Objetives.TargetObj.objIndex

50      If TieneObjetos(objIndex, ObjAmount, UserIndex) Then
60          Text = Campaign(.Current).Stages(tCurrentStage).Properties.Dialog.SecondTalk
70          Call ShowCampaignChat(UserIndex, NpcIndex, Text)
80          Call QuitarObjetos(objIndex, ObjAmount, UserIndex)
90          Call AccomplishObjetive(UserIndex, tCurrentStage)
100         Call WriteConsoleMsg(UserIndex, "¡Excelente! Has entregado los ítems del objetivo " & Campaign(.Current).Stages(tCurrentStage).Properties.Description & " de la misión.", FontTypeNames.FONTTYPE_CAMPAIGN)
110         .Stages(tCurrentStage).ObjDelivered = True

            '@ Si completó todos los objetivos, entonces podemos solicitar recompensa.
120         If .StagesCompleted = Campaign(.Current).Properties.NumStages Then
130             .WaitingReward = True
140         End If
150     Else
160         If Campaign(.Current).Stages(tCurrentStage).Objetives.TargetObj.objIndex > 0 Then
170             Call WriteConsoleMsg(UserIndex, "Te faltan " & ObjData(Campaign(.Current).Stages(tCurrentStage).Objetives.TargetObj.objIndex).Name & " " & Campaign(.Current).Stages(tCurrentStage).Properties.Description & " de la misión.", FontTypeNames.FONTTYPE_CAMPAIGN)
180         End If
190         .Stages(tCurrentStage).Done = False
200         Text = Campaign(.Current).Stages(tCurrentStage).Properties.Dialog.ThirdTalk
210         Call ShowCampaignChat(UserIndex, NpcIndex, Text)
220     End If

230 End With

240 On Error GoTo 0
250 Exit Function

DeliverObjects_Error:

260 Call LogError("Error " & err.Number & " (" & err.Description & ") procedimiento DeliverObjects Módulo modCampaign línea: " & Erl())

End Function

Public Sub CampaignBegin(ByVal UserIndex As Integer)

Dim i                           As Integer
Dim iTargetNpc                  As Integer
Dim Text                        As String

10  On Error GoTo CampaignBegin_Error

20  iTargetNpc = UserList(UserIndex).flags.TargetNPC

30  With UserList(UserIndex).Campaign

40      .Current = .CanDoThisOne
        '.CurrentStage = 1
50      .WaitingReward = False

60      If .Current > 0 Then

70          ReDim .Stages(1 To (Campaign(.Current).Properties.NumStages)) As UserStagesCampaign

80          If .OffererNpcIndex <> 0 Then
90              .NpcIndexGiver = NpcList(.OffererNpcIndex).ID
100         Else
110             Call FinishUncompletedCampaign(UserIndex, CampaignFailReason.Leave)
120             Exit Sub
130         End If             'Falto esto

140         .Timing = 0
150         .CanDoThisOne = 0
160         .OffererNpcIndex = 0
170         .CanViewCampaignList = False

180         For i = 1 To Campaign(.Current).Properties.NumStages
                '                If i = 1 Then
                '                    Call GiveStageObj(UserIndex, i)
                '                End If
190             .Stages(i).Done = False
200             .Stages(i).StageTiming = 0    'Campaign(.Current).Stages(i).Properties.Timing
            
210             .Stages(i).AmountTarget = 0 'NUEVO!
                '.Stages(i).AmountTargetNpc = 0
                '.Stages(i).AmountTargetUser = 0
                '.Stages(i).AmountTargetObj = 0
                
             .Stages(i).HaveToFoundPlace = (val(Campaign(.Current).Stages(i).Objetives.TargetLocation.Trigger) <> 0 Or (val(Campaign(.Current).Stages(i).Objetives.TargetLocation.posX) <> 0 And val(Campaign(.Current).Stages(i).Objetives.TargetLocation.posY) <> 0 And val(Campaign(.Current).Stages(i).Objetives.TargetLocation.Map)) <> 0)
                '.Stages(i).HaveToFoundPlace = 0 'Testeamos algo '@ Esto estaba MUY MAL.

                '                If Campaign(.Current).Stages(i).Objetives.TargetNPC.Action = 0 And Campaign(.Current).Stages(i).Objetives.TargetObj.objIndex > 0 Then
                '                    If TieneObjetos(Campaign(.Current).Stages(i).Objetives.TargetObj.objIndex, Campaign(.Current).Stages(i).Objetives.TargetObj.amount, UserIndex) Then
                '                        Call AccomplishObjetive(UserIndex, i)
                '                    End If
                '                End If
250         Next i

260         Text = Campaign(.Current).Properties.Dialog.SecondTalk

270         Call WriteConsoleMsg(UserIndex, "{997}", FontTypeNames.FONTTYPE_CAMPAIGN)    'Has aceptado la misión
280         Call WriteConsoleMsg(UserIndex, "{998}", FontTypeNames.FONTTYPE_CAMPAIGN)    'Escribe /INFOQUEST para ver los detalles de la misma.
290         Call WriteToggleCampaignState(UserIndex)

300         If UserList(UserIndex).flags.TargetNPC > 0 Then
310             Call ShowCampaignChat(UserIndex, UserList(UserIndex).flags.TargetNPC, Text)
320         Else
330             Call FinishUncompletedCampaign(UserIndex, CampaignFailReason.Leave)    ' Call ShowCampaignChat(UserIndex, .NpcIndexGiver, Text)
340         End If
350     Else
360         Call WriteConsoleMsg(UserIndex, "Misión cancelada.", FontTypeNames.FONTTYPE_CAMPAIGN)
370     End If
380 End With

390 On Error GoTo 0
400 Exit Sub

CampaignBegin_Error:

410 Call LogError("Error " & err.Number & " (" & err.Description & ") procedimiento CampaignBegin Módulo modCampaign línea: " & Erl())

End Sub

Public Sub CampaignTime(ByVal UserIndex As Integer)

    On Error GoTo CampaignTime_Error

20  With UserList(UserIndex).Campaign

30      If .Current > 0 And UserList(UserIndex).flags.UserLogged And UserList(UserIndex).ConnIDValida And Len(UserList(UserIndex).Name) > 0 Then
40          If Campaign(.Current).Properties.Timing > 0 Then
                '@ Tiempo de la misión en general.
50              If Not .WaitingReward Then
60                  .Timing = .Timing + 1
70                  If .Timing >= Campaign(.Current).Properties.Timing Then
80                      Call FinishUncompletedCampaign(UserIndex, CampaignFailReason.Timing)
90                  End If
100             End If
110         End If

            Dim i               As Integer
120         For i = 1 To Campaign(.Current).Properties.NumStages
                '@ Tiempo del objetivo actual.

                '@ Acá en teoría, debería consultar si la única misión que queda por hacer, tiene tiempo Pero eso también hay que datearlo de esa forma, sino el tiempo de la misión nunca va a funcionar si una misión tiene 3 objetivos totales, y 2 de ellas tienen tiempo.
130             If val(Campaign(.Current).Stages(i).Properties.Timing) > 0 Then
140                 If Not .Stages(i).Done Then
150                     .Stages(i).StageTiming = .Stages(i).StageTiming + 1
160                     If val(.Stages(i).StageTiming) >= val(Campaign(.Current).Stages(i).Properties.Timing) Then
170                         Call ReloadStageTimed(UserIndex)
180                     End If

190                     If val(Campaign(.Current).Stages(i).Properties.Timing) > 60 Then
200                         If .Stages(i).StageTiming Mod 60 = 0 Then
210                             Call WriteConsoleMsg(UserIndex, "Tienes " & Round((val(Campaign(.Current).Stages(i).Properties.Timing) - .Stages(i).StageTiming) / 60, 0) & " minutos restantes para completar el objetivo.", FontTypeNames.FONTTYPE_CAMPAIGN)
220                         End If
230                     End If
240                     Exit For    '@ Cerramos el bucle.
250                 End If
260             End If
270         Next i
280     End If

290 End With

    On Error GoTo 0
    Exit Sub

CampaignTime_Error:

    Call LogError("Error " & err.Number & " (" & err.Description & ") procedimiento CampaignTime Módulo modCampaign línea: " & Erl())

End Sub

Public Sub FinishUncompletedCampaign(ByVal UserIndex As Integer, ByVal Reason As Byte)

    On Error GoTo FinishUncompletedCampaign_Error

10  Call ResetCampaignTempData(UserIndex)
20  Call WriteCloseCampaignForms(UserIndex)

30  Select Case Reason
        Case CampaignFailReason.Leave
40          Call WriteConsoleMsg(UserIndex, "{1003}", FontTypeNames.FONTTYPE_CAMPAIGN)    '¡Has abandonado la misión!

50      Case CampaignFailReason.Reject
60          Call WriteConsoleMsg(UserIndex, "{1002}", FontTypeNames.FONTTYPE_ADMIN)    '¡Has rechazado la misión!

70      Case CampaignFailReason.Death
80          Call WriteConsoleMsg(UserIndex, "{1001}", FontTypeNames.FONTTYPE_CAMPAIGN)    '¡Has muerto en una misión!
90          Call WriteConsoleMsg(UserIndex, "{1000}", FontTypeNames.FONTTYPE_CAMPAIGN)    '¡No has podido terminar la misión!

100     Case CampaignFailReason.Timing
110         Call WriteConsoleMsg(UserIndex, "{999}", FontTypeNames.FONTTYPE_CAMPAIGN)    '¡Se ha agotado el tiempo para cumplir el objetivo!
120         Call WriteConsoleMsg(UserIndex, "{1000}", FontTypeNames.FONTTYPE_CAMPAIGN)    '¡No has podido terminar la misión!

130 End Select

140 Call WriteToggleCampaignState(UserIndex)

    On Error GoTo 0
    Exit Sub

FinishUncompletedCampaign_Error:

    Call LogError("Error " & err.Number & " (" & err.Description & ") procedimiento FinishUncompletedCampaign Módulo modCampaign línea: " & Erl())

End Sub

Public Sub ResetCampaignTempData(ByVal UserIndex As Integer)

Dim i                           As Integer

    On Error GoTo ResetCampaignTempData_Error

10  With UserList(UserIndex).Campaign

20      If .Current > 0 Then

            '.CurrentStage = 0
30          .StagesCompleted = 0
40          .WaitingReward = False
50          .NpcIndexGiver = 0
60          .Timing = 0
70          .CanDoThisOne = 0
80          .OffererNpcIndex = 0
90          .CanViewCampaignList = False

100         For i = 1 To Campaign(.Current).Properties.NumStages
110             .Stages(i).StageTiming = 0
120             .Stages(i).AmountTarget = 0 'NUEVO!
'120             .Stages(i).AmountTargetNpc = 0
'130             .Stages(i).AmountTargetUser = 0
'140             .Stages(i).AmountTargetObj = 0
150             .Stages(i).HaveToFoundPlace = False
160             .Stages(i).Done = False
170             .Stages(i).ObjDelivered = False
180         Next i

190         .Current = 0
200     End If
210 End With

    On Error GoTo 0
    Exit Sub

ResetCampaignTempData_Error:

    Call LogError("Error " & err.Number & " (" & err.Description & ") procedimiento ResetCampaignTempData Módulo modCampaign línea: " & Erl())

End Sub

Public Sub ResetCampaignAllData(ByVal UserIndex As Integer)

Dim i                           As Integer

    On Error GoTo ResetCampaignAllData_Error

10  With UserList(UserIndex).Campaign

        '.CurrentStage = 0
20      .StagesCompleted = 0
30      .WaitingReward = False
40      .NpcIndexGiver = 0
50      .Timing = 0

60      If .Current > 0 Then
70          For i = 1 To Campaign(.Current).Properties.NumStages
80              .Stages(i).StageTiming = 0
90              .Stages(i).AmountTarget = 0 'NUEVO!
'90              .Stages(i).AmountTargetNpc = 0
'100             .Stages(i).AmountTargetUser = 0
'110             .Stages(i).AmountTargetObj = 0
120             .Stages(i).HaveToFoundPlace = False
130             .Stages(i).Done = False
140             .Stages(i).ObjDelivered = False
150         Next i
160     End If

170     .CanDoThisOne = 0
180     .OffererNpcIndex = 0
190     .CanViewCampaignList = False
200     .CampaignsHasDone = vbNullString
210     .Current = 0
220 End With

    On Error GoTo 0
    Exit Sub

ResetCampaignAllData_Error:

    Call LogError("Error " & err.Number & " (" & err.Description & ") procedimiento ResetCampaignAllData Módulo modCampaign línea: " & Erl())

End Sub

Function AddPointer(ByRef LastPointer As Integer) As Integer
    LastPointer = LastPointer + 1
    AddPointer = LastPointer
End Function

Public Sub LoadUserCampaignData(ByVal UserIndex As Integer, Data As String)

Dim LastPoint                   As Integer

    On Error GoTo LoadUserCampaignData_Error

10  If Not StrComp(Data, vbNullString) = 0 Then    'About
20      With UserList(UserIndex).Campaign
            'Ejemplo: 19-0-218-0-19-0-0-0-0-0-14-0-0-0-0-0-0-1-0-0-0-0-0-0-0-0-0-0-0
30          .Current = val(ReadField(AddPointer(LastPoint), Data, 45)) '19
40          .WaitingReward = IIf(val(ReadField(AddPointer(LastPoint), Data, 45)), True, False) '0
50          .NpcIndexGiver = val(ReadField(AddPointer(LastPoint), Data, 45)) '218
60          .Timing = val(ReadField(AddPointer(LastPoint), Data, 45))

70          .CanDoThisOne = val(ReadField(AddPointer(LastPoint), Data, 45))
80          .OffererNpcIndex = val(ReadField(AddPointer(LastPoint), Data, 45))
90          .CanViewCampaignList = IIf(val(ReadField(AddPointer(LastPoint), Data, 45)) <> 0, True, False)
100         .StagesCompleted = val(ReadField(AddPointer(LastPoint), Data, 45))
            
110         If .Current > 0 Then
120             .CanDoThisOne = .Current

                Dim i           As Integer

130             ReDim .Stages(1 To Campaign(.Current).Properties.NumStages)
                
140             For i = 1 To Campaign(.Current).Properties.NumStages
150                 .Stages(i).Done = IIf(val(ReadField(AddPointer(LastPoint), Data, 45)) <> 0, True, False)
160                 .Stages(i).StageTiming = val(ReadField(AddPointer(LastPoint), Data, 45))
170                 .Stages(i).AmountTarget = val(ReadField(AddPointer(LastPoint), Data, 45)) 'NUEVO!
'170                 .Stages(i).AmountTargetNpc = val(ReadField(AddPointer(LastPoint), DATA, 45))
'180                 .Stages(i).AmountTargetUser = val(ReadField(AddPointer(LastPoint), DATA, 45))
'190                 .Stages(i).AmountTargetObj = val(ReadField(AddPointer(LastPoint), DATA, 45))
200                 .Stages(i).HaveToFoundPlace = IIf(val(ReadField(AddPointer(LastPoint), Data, 45)) <> 0, True, False)
210                 .Stages(i).ObjDelivered = IIf(val(ReadField(AddPointer(LastPoint), Data, 45)) <> 0, True, False)
220             Next i
230         End If

            'Debug.Print "Load Campaing Field counts: " & FieldCount(data, 45) & " must Be: " & (Campaign(UserList(UserIndex).Campaign.Current).Properties.NumStages * 6) + 8
240     End With
250 End If

    On Error GoTo 0
    Exit Sub

LoadUserCampaignData_Error:

    Call LogError("Error " & err.Number & " (" & err.Description & ") procedimiento LoadUserCampaignData Módulo modCampaign línea: " & Erl())

End Sub

Public Function SaveCampaignData(ByVal UserIndex As Integer) As clsFastString

10  On Error GoTo SaveCampaignData_Error

20  Set SaveCampaignData = New clsFastString

30  With UserList(UserIndex)
40      If .Campaign.Current > 0 Then
50          If Campaign(.Campaign.Current).Properties.FinishWhenDisconnect Then
60              SaveCampaignData.Clear
70              SaveCampaignData = SaveCampaignData.Value    'vbNullString
80          Else
90              With UserList(UserIndex).Campaign
                    'Dim finalString As String

100                 SaveCampaignData.Append CStr(.Current)
110                 SaveCampaignData.Append "-" & CStr(IIf(.WaitingReward, 1, 0))
120                 SaveCampaignData.Append "-" & CStr(.NpcIndexGiver)
130                 SaveCampaignData.Append "-" & CStr(.Timing)
140                 SaveCampaignData.Append "-" & CStr(.CanDoThisOne)
150                 SaveCampaignData.Append "-" & CStr(.OffererNpcIndex)
160                 SaveCampaignData.Append "-" & CStr(IIf(val(.CanViewCampaignList), 1, 0))
170                 SaveCampaignData.Append "-" & CStr(.StagesCompleted)

                    '8 strings

180                 If .Current > 0 Then
                        Dim i     As Integer

190                     For i = 1 To Campaign(.Current).Properties.NumStages

200                         SaveCampaignData.Append "-" & CStr(IIf(.Stages(i).Done, 1, 0))
210                         SaveCampaignData.Append "-" & CStr(.Stages(i).StageTiming)
220                         SaveCampaignData.Append "-" & CStr(.Stages(i).AmountTarget)

                            '190                         SaveCampaignData.Append "-" & CStr(.Stages(i).AmountTargetNpc)
                            '200                         SaveCampaignData.Append "-" & CStr(.Stages(i).AmountTargetUser)
                            '210                         SaveCampaignData.Append "-" & CStr(.Stages(i).AmountTargetObj)
230                         SaveCampaignData.Append "-" & CStr(IIf(.Stages(i).HaveToFoundPlace, 1, 0))
240                         SaveCampaignData.Append "-" & CStr(IIf(.Stages(i).ObjDelivered, 1, 0))
                            '6 strings por cada STAGE
250                     Next i
260                 End If

270             End With
280         End If
290     Else
300         SaveCampaignData.Clear
310         .Campaign.CampaignUnfinishSaved = SaveCampaignData.Value
320     End If

        'Debug.Print "SAVE Campaing Field counts: " & FieldCount(finalString, 45) & " must Be: " & (Campaign(UserList(UserIndex).Campaign.Current).Properties.NumStages * 6) + 8
330     .Campaign.CampaignUnfinishSaved = SaveCampaignData.Value

340 End With

350 On Error GoTo 0
360 Exit Function

SaveCampaignData_Error:

370 Call LogError("Error " & err.Number & " (" & err.Description & ") procedimiento SaveCampaignData Módulo modCampaign línea: " & Erl())

End Function

Public Sub ReloadStageTimed(ByVal UserIndex As Integer)

Dim i                           As Integer

    On Error GoTo ReloadStageTimed_Error

10  With UserList(UserIndex).Campaign

20      For i = 1 To Campaign(.Current).Properties.NumStages
30          If Not .Stages(i).Done And .Stages(i).StageTiming > 0 Then
40              .Stages(i).StageTiming = 0
50              .Stages(i).AmountTarget = 0 'NUEVO! 21/12/2020
'50              .Stages(i).AmountTargetNpc = 0
'60              .Stages(i).AmountTargetUser = 0
'70              .Stages(i).AmountTargetObj = 0
80              .Stages(i).ObjDelivered = False
90              .Stages(i).HaveToFoundPlace = val(Campaign(.Current).Stages(i).Objetives.TargetLocation.Trigger <> 0) Or (val(Campaign(.Current).Stages(i).Objetives.TargetLocation.posX <> 0) And val(Campaign(.Current).Stages(i).Objetives.TargetLocation.posY <> 0) And val(Campaign(.Current).Stages(i).Objetives.TargetLocation.Map <> 0))
100         End If
110     Next i

120     Call WriteConsoleMsg(UserIndex, "{999} Se ha reiniciado el objetivo.", FontTypeNames.FONTTYPE_CAMPAIGN)    '¡Se ha agotado el tiempo para cumplir el objetivo!
130     Call WriteUpdateCampaignInfo(UserIndex, .Current)

140 End With

    On Error GoTo 0
    Exit Sub

ReloadStageTimed_Error:

    Call LogError("Error " & err.Number & " (" & err.Description & ") procedimiento ReloadStageTimed Módulo modCampaign línea: " & Erl())

End Sub
Tengo uno recontra mil mejorado pero está muy adaptado a Bender.

Deberías laburar mucho en todo lo que es protocolo y eso, pero bueno, te lo dejo por si te sirve, porque es basado justamente en este que pedís:
 

Bramhh

Fundador EvolutionAo
Codigo modCampaings:
Option Explicit

Public Sub LoadCampaigns()

Dim tDesc                       As Boolean
Dim i                           As Long
Dim S                           As Long
Dim LoopA                       As Long
Dim LoopB                       As Long
Dim tRecompensa                 As New clsFastString
Dim Leer                        As New clsIniReader

10  On Error GoTo ErrHandler

20  Call WriteToConsole("Cargando campañas...")
    '    If frmCargando.Visible Then
    '        'frmCargando.Label1(2).Caption = "Cargando Campaings.AO"
    '    End If

30  If FileExist(DatPath & "Campaigns.AO", vbNormal) Then

        '/////////////////////////////////////////READ//BEGIN//////////////////////////////////////////////

40      Call Leer.Initialize(DatPath & "Campaigns.AO")

50      Set LeerCampaigns = Leer

60      NumCampaigns = val(Leer.GetValue("INIT", "NumCampaigns"))

70      ReDim Campaign(1 To NumCampaigns) As Campaign

80      For i = 1 To NumCampaigns

90          With Campaign(i)

                '////////////////////////////////////////READ//PROPERTIES//////////////////////////////////////////

100             With .Properties
110                 .Name = Leer.GetValue("Campaign" & i, "Name")
                    '            .Description = Leer.GetValue("Campaign" & i, "Description")    'Cambio de lugar la descripción, así podemos cargarla automáticamente.
                    '            .Description = .Description &  ")" 'Cierro el paréntesis aca.
120                 .Dialog.FirstTalk = Leer.GetValue("Campaign" & i, "Dialog1")
130                 .Dialog.SecondTalk = Leer.GetValue("Campaign" & i, "Dialog2")
140                 .Dialog.ThirdTalk = Leer.GetValue("Campaign" & i, "Dialog3")
150                 .Dialog.FourthTalk = Leer.GetValue("Campaign" & i, "Dialog4")
160                 .Dialog.FifthTalk = Leer.GetValue("Campaign" & i, "Dialog5")
170                 .NumStages = val(Leer.GetValue("Campaign" & i, "NumStages"))
180                 .Redoable = IIf(val(Leer.GetValue("Campaign" & i, "Redoable")) <> 0, True, False)
190                 .Timing = val(Leer.GetValue("Campaign" & i, "Time"))
200                 .FinishWhenDie = val(Leer.GetValue("Campaign" & i, "FinishWhenDie"))
210                 .FinishWhenDisconnect = val(Leer.GetValue("Campaign" & i, "FinishWhenDisconnect"))
220             End With

                '////////////////////////////////////////READ//REQUIREMENTS////////////////////////////////////////

230             With .Requirements
240                 .MinLvl = val(Leer.GetValue("Campaign" & i, "MinLvl"))
250                 .MaxLvl = val(Leer.GetValue("Campaign" & i, "MaxLvl"))
260                 .PreviousCampaign = val(Leer.GetValue("Campaign" & i, "PreviousCampaign"))
270                 .Class = val(Leer.GetValue("Campaign" & i, "Class"))
280                 .Race = val(Leer.GetValue("Campaign" & i, "Race"))
290                 .Genre = val(Leer.GetValue("Campaign" & i, "Genre"))
300                 .Alignment = val(Leer.GetValue("Campaign" & i, "Alignment"))
310                 .Faction = val(Leer.GetValue("Campaign" & i, "FACTION"))
320                 .Rank = val(Leer.GetValue("Campaign" & i, "Rank"))
330                 If .MinLvl > .MaxLvl And .MaxLvl > 0 Then .MinLvl = .MaxLvl

340             End With

                '/////////////////////////////////////////READ//REWARDS////////////////////////////////////////////

350             With .Rewards
360                 .PlateCoins = val(Leer.GetValue("Campaign" & i, "PlateCoins"))
370                 .EnlistFaction = val(Leer.GetValue("Campaign" & i, "EnlistFaction"))    '0 = Nada, 1 Armada, 2 Caos
380                 .Forgive = val(Leer.GetValue("Campaign" & i, "Forgive"))    'Perdon a los PKS!
390                 .RewardExp = val(Leer.GetValue("Campaign" & i, "RewardExp"))
400                 .RewardGold = val(Leer.GetValue("Campaign" & i, "RewardGold"))
410                 .NumRewardObj = val(Leer.GetValue("Campaign" & i, "NumRewardObj"))

420                 .RewardByClass = val(Leer.GetValue("Campaign" & i, "RewardByClass"))
430                 .NumRewardObjByClass = val(Leer.GetValue("Campaign" & i, "NumRewardObjByClass"))    'Cantidad de premios por clase, que van a recibir TODAS las clases. Siempre es la misma cantidad de premios para todas en una misma misión.

440                 tRecompensa.Clear

450                 If Campaign(i).Properties.FinishWhenDie Then
460                     If Len(tRecompensa.Value) = 0 Then
470                         tRecompensa.Append " INFO: Ésta mision se cancela al MORIR"
480                     Else
490                         tRecompensa.Append ", INFO: ésta mision se cancela al MORIR."
500                     End If
510                 End If

520                 If Campaign(i).Properties.FinishWhenDisconnect Then
530                     If Len(tRecompensa.Value) = 0 Then
540                         tRecompensa.Append " INFO: Ésta mision se cancela al DESCONECTARSE del juego."
550                     Else
560                         tRecompensa.Append ", INFO: ésta mision se cancela al DESCONECTARSE del juego."
570                     End If
580                 End If

590                 If Campaign(i).Properties.Timing > 0 Then
600                     If Len(tRecompensa.Value) = 0 Then
610                         tRecompensa.Append " INFO: Debes realizar la misión en menos de " & IIf(Campaign(i).Properties.Timing > 60, Campaign(i).Properties.Timing / 60 & " min.", Campaign(i).Properties.Timing & " seg.")
620                     Else
630                         tRecompensa.Append ", INFO: Debes realizar la misión en menos de " & IIf(Campaign(i).Properties.Timing > 60, Campaign(i).Properties.Timing / 60 & " min.", Campaign(i).Properties.Timing & " seg.")
640                     End If
650                 End If

660                 If .RewardExp > 0 Then
670                     If Len(tRecompensa.Value) = 0 Then
680                         tRecompensa.Append "Recompensa: " & .RewardExp & " de Experiencia"
690                     Else
700                         tRecompensa.Append ", " & .RewardExp & " de Experiencia"
710                     End If
720                 End If

730                 If .RewardGold > 0 Then
740                     If Len(tRecompensa.Value) = 0 Then
750                         tRecompensa.Append "Recompensa: " & .RewardGold & " de Oro"
760                     Else
770                         tRecompensa.Append ", " & .RewardGold & " de Oro"
780                     End If
790                 End If

800                 If .Forgive = 1 Then
810                     If Len(tRecompensa.Value) = 0 Then
820                         tRecompensa.Append "Recompensa: Volverás a ser Ciudadano"
830                     Else
840                         tRecompensa.Append ", y Volverás a ser Ciudadano"
850                     End If
860                 End If

870                 Select Case .EnlistFaction
                        Case 1

880                         If Len(tRecompensa.Value) = 0 Then
890                             If BonusExpArmy > 0 Then
900                                 tRecompensa.Append "Recompensa: Enlistarse en el Ejército Real y Ganarás " & BonusExpArmy & "% más de experiencia."
910                             Else
920                                 tRecompensa.Append "Recompensa: Enlistarse en el Ejército Real."
930                             End If
940                         Else
950                             If BonusExpArmy > 0 Then
960                                 tRecompensa.Append ", Enlistarse en el Ejército Real y Ganarás " & BonusExpArmy & "% más de experiencia."
970                             Else
980                                 tRecompensa.Append ", Enlistarse en el Ejército Real"
990                             End If
1000                        End If
1010                    Case 2
1020                        If Len(tRecompensa.Value) = 0 Then
1030                            If BonusExpCaos > 0 Then
1040                                tRecompensa.Append "Recompensa: Enlistarse en la Legión Oscura y ganarás " & BonusExpCaos & "% más de experiencia"
1050                            Else
1060                                tRecompensa.Append "Recompensa: Enlistarse en la Legión Oscura."
1070                            End If
1080                        Else
1090                            If BonusExpCaos > 0 Then
1100                                tRecompensa.Append ", Recompensa: Enlistarse en la Legión Oscura y ganarás " & BonusExpCaos & "% más de experiencia"
1110                            Else
1120                                tRecompensa.Append ", Recompensa: Enlistarse en la Legión Oscura."
1130                            End If
1140                        End If
1150                    Case 3
1160                        If Len(tRecompensa.Value) = 0 Then
1170                            tRecompensa.Append "Recompensa: Ser miembro del Consejo Mercenario."
1180                        Else
1190                            tRecompensa.Append ", Ser miembro del Consejo Mercenario."
1200                        End If
1210                End Select

1220                If Not .NumRewardObj <= 0 Then

1230                    ReDim .RewardObj(1 To .NumRewardObj) As Obj

1240                    For LoopA = 1 To .NumRewardObj
1250                        .RewardObj(LoopA).objIndex = val(Leer.GetValue("Campaign" & i, "RewardObj" & LoopA & "Index"))
1260                        .RewardObj(LoopA).amount = val(Leer.GetValue("Campaign" & i, "RewardObj" & LoopA & "Amount"))

1270                        If .RewardObj(LoopA).amount > 0 Then
1280                            If Len(tRecompensa.Value) Then
1290                                tRecompensa.Append "Recompensa: " & IIf(.RewardObj(LoopA).amount > 1, .RewardObj(LoopA).amount & " ", "") & ObjData(.RewardObj(LoopA).objIndex).Name
1300                            Else
1310                                tRecompensa.Append ", " & IIf(.RewardObj(LoopA).amount > 1, .RewardObj(LoopA).amount & " ", "") & ObjData(.RewardObj(LoopA).objIndex).Name
1320                            End If
                                'Debug.Print "REcompensa: " & tRecompensa
1330                        Else
1340                            .NumRewardObj = .NumRewardObj - 1    '@ Fixiame el error automáticamente.
1350                        End If
1360                    Next LoopA

1370                Else
1380                    ReDim .RewardObj(0)
1390                End If

1400                If .NumRewardObjByClass > 0 Then
1410                    If .NumRewardObjByClass > MAX_INVENTORY_SLOTS Then .NumRewardObjByClass = MAX_INVENTORY_SLOTS    'MAX 25!!
1420                    For LoopA = 1 To NUMCLASES
1430                        For LoopB = 1 To .NumRewardObjByClass    'MAX 25!!
1440                            If val(Leer.GetValue("Campaign" & i, "Class" & LoopA & "ObjIndex" & LoopB)) > 0 Then
1450                                .RewardObjByClass(LoopA).ClassReward(LoopB).objIndex = val(Leer.GetValue("Campaign" & i, "Class" & LoopA & "ObjIndex" & LoopB))
1460                                .RewardObjByClass(LoopA).ClassReward(LoopB).amount = val(Leer.GetValue("Campaign" & i, "Class" & LoopA & "ObjAmount" & LoopB))

1470                                If .RewardObjByClass(LoopA).ClassReward(LoopB).amount > 0 Then
1480                                    If Len(.RewardObjByClass(LoopA).Description) = 0 Then
1490                                        .RewardObjByClass(LoopA).Description = "Extra: " & IIf(.RewardObjByClass(LoopA).ClassReward(LoopB).amount > 1, .RewardObjByClass(LoopA).ClassReward(LoopB).amount & " ", "") & " " & ObjData(.RewardObjByClass(LoopA).ClassReward(LoopB).objIndex).Name
1500                                    Else
1510                                        .RewardObjByClass(LoopA).Description = .RewardObjByClass(LoopA).Description & ", " & IIf(.RewardObjByClass(LoopA).ClassReward(LoopB).amount > 1, .RewardObjByClass(LoopA).ClassReward(LoopB).amount & " ", "") & ObjData(.RewardObjByClass(LoopA).ClassReward(LoopB).objIndex).Name
1520                                    End If
1530                                Else
1540                                    .NumRewardObjByClass = .NumRewardObjByClass - 1
1550                                End If
1560                            End If
1570                        Next LoopB
1580                    Next LoopA
1590                End If

1600                tRecompensa.Append " |||| "    '& tRecompensa    '@ Emprolijo un poco el cartel.

1610                .Description = Leer.GetValue("Campaign" & i, "Description")    'Añadimos la descripción junto con las recompensas de forma automáticas.
1620                .Description = .Description & tRecompensa.Value
                    '.RewardDescription = tRecompensa
1630            End With

                '/////////////////////////////////////////READ//STAGES/////////////////////////////////////////////

1640            ReDim .Stages(1 To .Properties.NumStages) As CampaignStage

1650            For S = 1 To .Properties.NumStages

1660                With .Stages(S)
1670                    With .Properties
1680                        .Description = Leer.GetValue("Campaign" & i & " - Stage" & S, "Description")
1690                        .Dialog.FirstTalk = Leer.GetValue("Campaign" & i & " - Stage" & S, "Dialog1")
1700                        .Dialog.SecondTalk = Leer.GetValue("Campaign" & i & " - Stage" & S, "Dialog2")
1710                        .Dialog.ThirdTalk = Leer.GetValue("Campaign" & i & " - Stage" & S, "Dialog3")
1720                        .Dialog.FourthTalk = ""
1730                        .Dialog.FifthTalk = ""
1740                        .Timing = val(Leer.GetValue("Campaign" & i & " - Stage" & S, "Time"))
1750                        .StageRequired = val(Leer.GetValue("Campaign" & i & " - Stage" & S, "StageRequired"))
1760                    End With

1770                    With .Objetives
1780                        .TargetNPC.Index = val(Leer.GetValue("Campaign" & i & " - Stage" & S, "TargetNpcIndex"))
1790                        .TargetNPC.amount = val(Leer.GetValue("Campaign" & i & " - Stage" & S, "TargetNpcAmount"))
1800                        .TargetNPC.Action = val(Leer.GetValue("Campaign" & i & " - Stage" & S, "TargetNpcAction"))
1810                        .TargetObj.objIndex = val(Leer.GetValue("Campaign" & i & " - Stage" & S, "TargetObjIndex"))
1820                        .TargetObj.amount = val(Leer.GetValue("Campaign" & i & " - Stage" & S, "TargetObjAmount"))
1830                        .TargetUser.MinLvl = val(Leer.GetValue("Campaign" & i & " - Stage" & S, "TargetUserMinLvl"))
1840                        .TargetUser.MaxLvl = val(Leer.GetValue("Campaign" & i & " - Stage" & S, "TargetUserMaxLvl"))
1850                        .TargetUser.amount = val(Leer.GetValue("Campaign" & i & " - Stage" & S, "TargetUserAmount"))
1860                        .TargetUser.Alignment = val(Leer.GetValue("Campaign" & i & " - Stage" & S, "TargetUserAlignment"))
1870                        .TargetUser.Faction = val(Leer.GetValue("Campaign" & i & " - Stage" & S, "TargetUserFACTION"))
1880                        .TargetUser.Rank = val(Leer.GetValue("Campaign" & i & " - Stage" & S, "TargetUserRank"))
1890                        .TargetLocation.Trigger = val(Leer.GetValue("Campaign" & i & " - Stage" & S, "TargetLocationTrigger"))
1900                        .TargetLocation.posX = val(Leer.GetValue("Campaign" & i & " - Stage" & S, "TargetLocationPosX"))
1910                        .TargetLocation.posY = val(Leer.GetValue("Campaign" & i & " - Stage" & S, "TargetLocationPosY"))
1920                        .TargetLocation.Map = val(Leer.GetValue("Campaign" & i & " - Stage" & S, "TargetLocationMap"))
1930                        .KeyWord = Leer.GetValue("Campaign" & i & " - Stage" & S, "KeyWord")
1940                    End With

1950                    .NumGivenObj = val(Leer.GetValue("Campaign" & i & " - Stage" & S, "NumGivenObj"))

1960                    If Not .NumGivenObj = 0 Then

1970                        ReDim .GivenObj(1 To .NumGivenObj) As Obj

1980                        For LoopB = 1 To .NumGivenObj
1990                            .GivenObj(LoopB).objIndex = val(Leer.GetValue("Campaign" & i & " - Stage" & S, "GivenObj" & LoopB & "Index"))
2000                            .GivenObj(LoopB).amount = val(Leer.GetValue("Campaign" & i & " - Stage" & S, "GivenObj" & LoopB & "Amount"))
2010                        Next LoopB

2020                    Else
2030                        ReDim .GivenObj(0)
2040                    End If

2050                End With

2060            Next S

2070        End With

2080    Next i

        '/////////////////////////////////////////READ//END////////////////////////////////////////////////

2090 Else
2100    Call WriteToConsole("Cargando campañas default...")
2110    Call LoadDefaultCampaigns

2120 End If

2130 Call WriteToConsole("Camapañas cargadas correctamente.")
2140 Set Leer = Nothing

2150 Exit Sub
ErrHandler:
2160 Call LogError("Error al cargar campañas. Se cargará la campaña por defecto " & err.Number & ": " & err.Description & " Linea: " & Erl)
2170 Call LoadDefaultCampaigns

End Sub

Public Sub LoadDefaultCampaigns()

10  On Error GoTo LoadDefaultCampaigns_Error

20  NumCampaigns = 2

30  ReDim Campaign(1 To NumCampaigns) As Campaign

40  With Campaign(1)

50      With .Properties
60          .Name = "Cacería de Lobos"
70          Campaign(1).Rewards.Description = "Debes matar 20 lobos y entregarme sus pieles"
80          .Dialog.FirstTalk = "Hola aventurero tengo una misión para ti!"
90          .Dialog.SecondTalk = "Esta daga puede servirte. Ahora ve en busca de esas criaturas!"
100         .Dialog.ThirdTalk = "¿Todavía no tienes las pieles?"
110         .Dialog.FourthTalk = "Ah! Veo que vienes en busca de tu recompensa"
120         .Dialog.FifthTalk = "Toma esta espada y este hechizo"
130         .NumStages = 2
140         .Redoable = 1
150         .Timing = 0
160         .FinishWhenDie = True
170     End With

180     With .Requirements
190         .MinLvl = 1
200         .MaxLvl = 45
210         .PreviousCampaign = 0
220         .Class = 0
230         .Race = 0
240         .Genre = 0
250         .Alignment = 0
260         .Faction = 0
270         .Rank = 0
280     End With

290     With .Rewards
300         .RewardExp = 1500
310         .RewardGold = 1500
320         .NumRewardObj = 2
330         ReDim .RewardObj(1 To .NumRewardObj) As Obj
340         .RewardObj(1).objIndex = 197
350         .RewardObj(1).amount = 1
360         .RewardObj(2).objIndex = 164
370         .RewardObj(2).amount = 1
380     End With

390     ReDim .Stages(1 To .Properties.NumStages) As CampaignStage

400     With .Stages(1)
410         With .Properties
420             .Description = "Matar 20 lobos"
430             .Dialog.FirstTalk = vbNullString
440             .Dialog.SecondTalk = vbNullString
450             .Dialog.ThirdTalk = vbNullString
460             .Dialog.FourthTalk = vbNullString
470             .Dialog.FifthTalk = vbNullString
480             .Timing = 0
490         End With

500         With .Objetives
510             .TargetNPC.Index = 501
520             .TargetNPC.amount = 20
530             .TargetNPC.Action = 1
540             .TargetObj.objIndex = 0
550             .TargetObj.amount = 0
560             .TargetUser.MinLvl = 0
570             .TargetUser.MaxLvl = 0
580             .TargetUser.amount = 0
590             .TargetUser.Alignment = 0
600             .TargetUser.Faction = 0
610             .TargetUser.Rank = 0
620             .TargetLocation.Trigger = 0
630             .TargetLocation.posX = 0
640             .TargetLocation.posY = 0
650             .TargetLocation.Map = 0
660             .KeyWord = ""
670         End With

680         .NumGivenObj = 1
690         ReDim .GivenObj(1 To .NumGivenObj) As Obj
700         .GivenObj(1).objIndex = 165
710         .GivenObj(1).amount = 1
720     End With

730     With .Stages(2)
740         With .Properties
750             .Description = "Entregar las pieles"
760             .Dialog.FirstTalk = vbNullString
770             .Dialog.SecondTalk = vbNullString
780             .Dialog.ThirdTalk = vbNullString
790             .Dialog.FourthTalk = vbNullString
800             .Dialog.FifthTalk = vbNullString
810             .Timing = 0
820         End With

830         With .Objetives
840             .TargetNPC.Index = 128
850             .TargetNPC.amount = 0
860             .TargetNPC.Action = 3
870             .TargetObj.objIndex = 414
880             .TargetObj.amount = 20
890             .TargetUser.MinLvl = 0
900             .TargetUser.MaxLvl = 0
910             .TargetUser.amount = 0
920             .TargetUser.Alignment = 0
930             .TargetUser.Faction = 0
940             .TargetUser.Rank = 0
950             .TargetLocation.Trigger = 0
960             .TargetLocation.posX = 0
970             .TargetLocation.posY = 0
980             .TargetLocation.Map = 0
990             .KeyWord = ""
1000        End With

1010        .NumGivenObj = 0
1020        ReDim .GivenObj(0)
1030    End With

1040 End With

1050 With Campaign(2)

1060    With .Properties
1070        .Name = "Tumulto en la ciudad"
1080        Campaign(2).Rewards.Description = "Le han robado al Gobernador y necesitamos que averigues quién fue"
1090        .Dialog.FirstTalk = "Tengo un trabajo para ofrecerte!"
1100        .Dialog.SecondTalk = "Ve a hablar con el sacerdote. Apresúrate!"
1110        .Dialog.ThirdTalk = "¿Todavía no tienes la información? Si la tienes ve a decirle al Gobernador!"
1120        .Dialog.FourthTalk = "Ah! Veo que vienes en busca de tu recompensa"
1130        .Dialog.FifthTalk = "Gracias por tu ayuda! Estos objetos te servirán para tu entrenamiento"
1140        .NumStages = 7
1150        .Redoable = 1
1160        .Timing = 0
1170        .FinishWhenDie = False
1180    End With

1190    With .Requirements
1200        .MinLvl = 1
1210        .MaxLvl = 45
1220        .PreviousCampaign = 0
1230        .Class = 0
1240        .Race = 0
1250        .Genre = 0
1260        .Alignment = 0
1270        .Faction = 0
1280        .Rank = 0
1290    End With

1300    With .Rewards
1310        .RewardExp = 15000
1320        .RewardGold = 1500000
1330        .NumRewardObj = 4
1340        ReDim .RewardObj(1 To .NumRewardObj) As Obj
1350        .RewardObj(1).objIndex = 238
1360        .RewardObj(1).amount = 1
1370        .RewardObj(2).objIndex = 366
1380        .RewardObj(2).amount = 1
1390        .RewardObj(3).objIndex = 38
1400        .RewardObj(3).amount = 10000
1410        .RewardObj(4).objIndex = 205
1420        .RewardObj(4).amount = 1
1430    End With

1440    ReDim .Stages(1 To .Properties.NumStages) As CampaignStage

1450    With .Stages(1)
1460        With .Properties
1470            .Description = "Hablar con el sacerdote"
1480            .Dialog.FirstTalk = "He oído los rumores pero no se quién es el ladrón. Quizás Cullighan sepa. El vende propiedades."
1490            .Dialog.SecondTalk = vbNullString
1500            .Dialog.ThirdTalk = vbNullString
1510            .Dialog.FourthTalk = vbNullString
1520            .Dialog.FifthTalk = vbNullString
1530            .Timing = 0
1540        End With

1550        With .Objetives
1560            .TargetNPC.Index = 5
1570            .TargetNPC.amount = 0
1580            .TargetNPC.Action = 2
1590            .TargetObj.objIndex = 0
1600            .TargetObj.amount = 0
1610            .TargetUser.MinLvl = 0
1620            .TargetUser.MaxLvl = 0
1630            .TargetUser.amount = 0
1640            .TargetUser.Alignment = 0
1650            .TargetUser.Faction = 0
1660            .TargetUser.Rank = 0
1670            .TargetLocation.Trigger = 0
1680            .TargetLocation.posX = 0
1690            .TargetLocation.posY = 0
1700            .TargetLocation.Map = 0
1710            .KeyWord = ""
1720        End With

1730        .NumGivenObj = 0
1740        ReDim .GivenObj(0)
1750    End With

1760    With .Stages(2)
1770        With .Properties
1780            .Description = "Hablar con Cullighan"
1790            .Dialog.FirstTalk = "Puede ser que yo sepa quién es el ladrón, pero deberás traerme 5 cervezas si quieres mi ayuda"
1800            .Dialog.SecondTalk = vbNullString
1810            .Dialog.ThirdTalk = vbNullString
1820            .Dialog.FourthTalk = vbNullString
1830            .Dialog.FifthTalk = vbNullString
1840            .Timing = 0
1850        End With

1860        With .Objetives
1870            .TargetNPC.Index = 34
1880            .TargetNPC.amount = 0
1890            .TargetNPC.Action = 2
1900            .TargetObj.objIndex = 0
1910            .TargetObj.amount = 0
1920            .TargetUser.MinLvl = 0
1930            .TargetUser.MaxLvl = 0
1940            .TargetUser.amount = 0
1950            .TargetUser.Alignment = 0
1960            .TargetUser.Faction = 0
1970            .TargetUser.Rank = 0
1980            .TargetLocation.Trigger = 0
1990            .TargetLocation.posX = 0
2000            .TargetLocation.posY = 0
2010            .TargetLocation.Map = 0
2020            .KeyWord = ""
2030        End With

2040        .NumGivenObj = 0
2050        ReDim .GivenObj(0)
2060    End With

2070    With .Stages(3)
2080        With .Properties
2090            .Description = "Conseguir 5 cervezas"
2100            .Dialog.FirstTalk = vbNullString
2110            .Dialog.SecondTalk = vbNullString
2120            .Dialog.ThirdTalk = vbNullString
2130            .Dialog.FourthTalk = vbNullString
2140            .Dialog.FifthTalk = vbNullString
2150            .Timing = 0
2160        End With

2170        With .Objetives
2180            .TargetNPC.Index = 0
2190            .TargetNPC.amount = 0
2200            .TargetNPC.Action = 0
2210            .TargetObj.objIndex = 160
2220            .TargetObj.amount = 5
2230            .TargetUser.MinLvl = 0
2240            .TargetUser.MaxLvl = 0
2250            .TargetUser.amount = 0
2260            .TargetUser.Alignment = 0
2270            .TargetUser.Faction = 0
2280            .TargetUser.Rank = 0
2290            .TargetLocation.Trigger = 0
2300            .TargetLocation.posX = 0
2310            .TargetLocation.posY = 0
2320            .TargetLocation.Map = 0
2330            .KeyWord = ""
2340        End With

2350        .NumGivenObj = 0
2360        ReDim .GivenObj(0)
2370    End With

2380    With .Stages(4)
2390        With .Properties
2400            .Description = "Llevarle las cervezas a Cullighan"
2410            .Dialog.FirstTalk = "Vamos hombre! Todavía estoy esperando!"
2420            .Dialog.SecondTalk = "Hip Hip... Lo he olvidado. Habla con Nelmasil, el pregonero, el seguro te va a ayudar Hip Hip!"
2430            .Dialog.ThirdTalk = "No intentes pasarte de listo! No tienes la cantidad que te pedí!"
2440            .Dialog.FourthTalk = vbNullString
2450            .Dialog.FifthTalk = vbNullString
2460            .Timing = 0
2470        End With

2480        With .Objetives
2490            .TargetNPC.Index = 34
2500            .TargetNPC.amount = 0
2510            .TargetNPC.Action = 3
2520            .TargetObj.objIndex = 160
2530            .TargetObj.amount = 5
2540            .TargetUser.MinLvl = 0
2550            .TargetUser.MaxLvl = 0
2560            .TargetUser.amount = 0
2570            .TargetUser.Alignment = 0
2580            .TargetUser.Faction = 0
2590            .TargetUser.Rank = 0
2600            .TargetLocation.Trigger = 0
2610            .TargetLocation.posX = 0
2620            .TargetLocation.posY = 0
2630            .TargetLocation.Map = 0
2640            .KeyWord = ""
2650        End With

2660        .NumGivenObj = 0
2670        ReDim .GivenObj(0)
2680    End With

2690    With .Stages(5)
2700        With .Properties
2710            .Description = "Hablar con Nelmasil"
2720            .Dialog.FirstTalk = "Me importa un comino lo que le pase al Gobernador!! Ve a buscar ayuda en otro lado. Los sastres siempre tienen información"
2730            .Dialog.SecondTalk = vbNullString
2740            .Dialog.ThirdTalk = vbNullString
2750            .Dialog.FourthTalk = vbNullString
2760            .Dialog.FifthTalk = vbNullString
2770            .Timing = 0
2780        End With

2790        With .Objetives
2800            .TargetNPC.Index = 128
2810            .TargetNPC.amount = 0
2820            .TargetNPC.Action = 2
2830            .TargetObj.objIndex = 0
2840            .TargetObj.amount = 0
2850            .TargetUser.MinLvl = 0
2860            .TargetUser.MaxLvl = 0
2870            .TargetUser.amount = 0
2880            .TargetUser.Alignment = 0
2890            .TargetUser.Faction = 0
2900            .TargetUser.Rank = 0
2910            .TargetLocation.Trigger = 0
2920            .TargetLocation.posX = 0
2930            .TargetLocation.posY = 0
2940            .TargetLocation.Map = 0
2950            .KeyWord = ""
2960        End With

2970        .NumGivenObj = 0
2980        ReDim .GivenObj(0)
2990    End With

3000    With .Stages(6)
3010        With .Properties
3020            .Description = "Hablar con uno de los sastres"
3030            .Dialog.FirstTalk = "Yo se quién ha sido el ladrón. Pero necesito mates 30 serpientes porque me vuelvan loca y no puedo trabajar!! Luego regresa a hablar conmigo"
3040            .Dialog.SecondTalk = vbNullString
3050            .Dialog.ThirdTalk = vbNullString
3060            .Dialog.FourthTalk = vbNullString
3070            .Dialog.FifthTalk = vbNullString
3080            .Timing = 0
3090        End With

3100        With .Objetives
3110            .TargetNPC.Index = 19
3120            .TargetNPC.amount = 0
3130            .TargetNPC.Action = 2
3140            .TargetObj.objIndex = 0
3150            .TargetObj.amount = 0
3160            .TargetUser.MinLvl = 0
3170            .TargetUser.MaxLvl = 0
3180            .TargetUser.amount = 0
3190            .TargetUser.Alignment = 0
3200            .TargetUser.Faction = 0
3210            .TargetUser.Rank = 0
3220            .TargetLocation.Trigger = 0
3230            .TargetLocation.posX = 0
3240            .TargetLocation.posY = 0
3250            .TargetLocation.Map = 0
3260            .KeyWord = ""
3270        End With

3280        .NumGivenObj = 0
3290        ReDim .GivenObj(0)
3300    End With

3310    With .Stages(7)
3320        With .Properties
3330            .Description = "Matar 3 serpientes"
3340            .Dialog.FirstTalk = vbNullString
3350            .Dialog.SecondTalk = vbNullString
3360            .Dialog.ThirdTalk = vbNullString
3370            .Dialog.FourthTalk = vbNullString
3380            .Dialog.FifthTalk = vbNullString
3390            .Timing = 0
3400        End With

3410        With .Objetives
3420            .TargetNPC.Index = 504
3430            .TargetNPC.amount = 3
3440            .TargetNPC.Action = 1
3450            .TargetObj.objIndex = 0
3460            .TargetObj.amount = 0
3470            .TargetUser.MinLvl = 0
3480            .TargetUser.MaxLvl = 0
3490            .TargetUser.amount = 0
3500            .TargetUser.Alignment = 0
3510            .TargetUser.Faction = 0
3520            .TargetUser.Rank = 0
3530            .TargetLocation.Trigger = 0
3540            .TargetLocation.posX = 0
3550            .TargetLocation.posY = 0
3560            .TargetLocation.Map = 0
3570            .KeyWord = ""
3580        End With

3590        .NumGivenObj = 0
3600        ReDim .GivenObj(0)
3610    End With

3620    With .Stages(8)
3630        With .Properties
3640            .Description = "Volver a hablar con la sastre"
3650            .Dialog.FirstTalk = "Muchas gracias por matar esas criaturas. Ahora te lo diré! El ladrón es... Nelmasil!!!"
3660            .Dialog.SecondTalk = vbNullString
3670            .Dialog.ThirdTalk = vbNullString
3680            .Dialog.FourthTalk = vbNullString
3690            .Dialog.FifthTalk = vbNullString
3700            .Timing = 0
3710        End With

3720        With .Objetives
3730            .TargetNPC.Index = 19
3740            .TargetNPC.amount = 0
3750            .TargetNPC.Action = 2
3760            .TargetObj.objIndex = 0
3770            .TargetObj.amount = 0
3780            .TargetUser.MinLvl = 0
3790            .TargetUser.MaxLvl = 0
3800            .TargetUser.amount = 0
3810            .TargetUser.Alignment = 0
3820            .TargetUser.Faction = 0
3830            .TargetUser.Rank = 0
3840            .TargetLocation.Trigger = 0
3850            .TargetLocation.posX = 0
3860            .TargetLocation.posY = 0
3870            .TargetLocation.Map = 0
3880            .KeyWord = ""
3890        End With

3900        .NumGivenObj = 0
3910        ReDim .GivenObj(0)
3920    End With

3930    With .Stages(9)
3940        With .Properties
3950            .Description = "Decirle al Gobernador quién es el ladrón"
3960            .Dialog.FirstTalk = vbNullString
3970            .Dialog.SecondTalk = vbNullString
3980            .Dialog.ThirdTalk = vbNullString
3990            .Dialog.FourthTalk = vbNullString
4000            .Dialog.FifthTalk = vbNullString
4010            .Timing = 0
4020        End With

4030        With .Objetives
4040            .TargetNPC.Index = 13
4050            .TargetNPC.amount = 0
4060            .TargetNPC.Action = 5
4070            .TargetObj.objIndex = 0
4080            .TargetObj.amount = 0
4090            .TargetUser.MinLvl = 0
4100            .TargetUser.MaxLvl = 0
4110            .TargetUser.amount = 0
4120            .TargetUser.Alignment = 0
4130            .TargetUser.Faction = 0
4140            .TargetUser.Rank = 0
4150            .TargetLocation.Trigger = 0
4160            .TargetLocation.posX = 0
4170            .TargetLocation.posY = 0
4180            .TargetLocation.Map = 0
4190            .KeyWord = "Nelmasil"
4200        End With

4210        .NumGivenObj = 0
4220        ReDim .GivenObj(0)
4230    End With
4240 End With

4250 On Error GoTo 0
4260 Exit Sub

LoadDefaultCampaigns_Error:

4270 Call LogError("Error " & err.Number & " Descripción: & (" & err.Description & ") del procedimiento LoadDefaultCampaigns del Módulo mod_Campaing" & " En la linea: " & Erl)

End Sub

Public Function CanDoThisCampaign(ByVal UserIndex As Integer, ByVal Number As Integer, ByRef sErrorMsg As String) As Boolean

'Función para saber si el usuario puede realizar la Campaña Number

Dim Alignment                   As Byte    '1)Ciudadano 2)Criminal
Dim Faction                     As Byte    '1)Armada 2)Caos

10  On Error GoTo CanDoThisCampaign_Error

20  Dim Rank                    As Byte    'Armada: 1)Aprendiz 2)Escudero 3)Soldado 4)Sargento 5)Teniente 6)Comandante 7)Capitán 8)Senescal 9)Mariscal 10)Condestable 11)Ejecutor Imperial 12)Protector del Reino 13)Avatar de la Justicia 14)Guardián del Bien 15)Campeón de la Luz
    'Caos: 1)Acólito 2)Alama Corrupta 3)Paria 4)Condenado 5)Esbirro 6)Sanguinario 7)Corruptor 8)Heraldo Impío 9)Caballero de la Oscuridad 10)Señor del Miedo 11)Ejecutor Infernal 12)Protector del Averno 13)Avatar de la Destrucción 14)Guardián del Mal 15)Campeón de la Oscuridad

30  With UserList(UserIndex)

40      If Criminal(UserIndex) Then
50          Alignment = 2
60      Else
70          Alignment = 1
80      End If

90      If esArmada(UserIndex) Then
100         Faction = 1
110     ElseIf esCaos(UserIndex) Then
120         Faction = 2
130     Else
140         Faction = 0
150     End If

160     If Faction = 1 Then
170         Rank = (.Faccion.RangeRoyal)
180     ElseIf Faction = 2 Then
190         Rank = (.Faccion.RangeCaos)
200     Else
210         Rank = 0
220     End If

230     If Number > NumCampaigns Then
240         Call LogError("El usuario: " & .Name & " intenta realizar una misión que supera el numero máximo de misiones, numero: " & Number & " Cantidad máxima de misiones: " & NumCampaigns)
250         sErrorMsg = "Estás intentando realizar una misión inválida. Avisa a un administrador."
260         Exit Function
270     End If

280     If Number > 0 Then
290         If .Stats.ELV < Campaign(Number).Requirements.MinLvl Then
300             sErrorMsg = "{1004}" & IIf(Campaign(Number).Requirements.MinLvl > 0, " como mínimo " & Campaign(Number).Requirements.MinLvl, "") & IIf(Campaign(Number).Requirements.MaxLvl > 0, " como máximo " & Campaign(Number).Requirements.MaxLvl, "") & " para realizar la misión " & Campaign(Number).Properties.Name
310             Exit Function
320         End If

330         If Campaign(Number).Requirements.MaxLvl <> 0 And .Stats.ELV > Campaign(Number).Requirements.MaxLvl Then
340             sErrorMsg = "{1004}" & IIf(Campaign(Number).Requirements.MinLvl > 0, " como mínimo " & Campaign(Number).Requirements.MinLvl, "") & IIf(Campaign(Number).Requirements.MaxLvl > 0, " como máximo " & Campaign(Number).Requirements.MaxLvl, "") & " para realizar la misión " & Campaign(Number).Properties.Name
350             Exit Function
360         End If

370         If Campaign(Number).Requirements.Class <> 0 And .Clase <> Campaign(Number).Requirements.Class Then
380             sErrorMsg = "{1005}"    'La misión no es para tu clase.
390             Exit Function
400         End If

410         If Campaign(Number).Requirements.Race <> 0 And .raza <> Campaign(Number).Requirements.Race Then
420             sErrorMsg = "{1006}"    'La misión no es para tu raza.
430             Exit Function
440         End If

450         If Campaign(Number).Requirements.Genre <> 0 And .Genero <> Campaign(Number).Requirements.Genre Then
460             sErrorMsg = "{1007}"    'La misión no es para tu genero o sexo.
470             Exit Function
480         End If

490         If Campaign(Number).Requirements.PreviousCampaign <> 0 Then
500             If Not HasDoneThisCampaign(UserIndex, Campaign(Number).Requirements.PreviousCampaign) Then
510                 sErrorMsg = "{1008}" & Campaign(Number).Requirements.PreviousCampaign & " llamada: " & Campaign(Campaign(Number).Requirements.PreviousCampaign).Properties.Name    'Para realizar esta misión, necesitas tener realizada previamente la misión número
520                 Exit Function
530             End If
540         End If

550         If Campaign(Number).Requirements.Alignment <> 0 And Alignment <> Campaign(Number).Requirements.Alignment Then
560             sErrorMsg = "{1009}"    'La misión no es para tu alineación o status.
570             Exit Function
580         End If

590         If Campaign(Number).Requirements.Faction <> 0 And Faction <> Campaign(Number).Requirements.Faction Then
600             sErrorMsg = "{1010}"    'La misión no es para tu facción.
610             Exit Function
620         End If

630         If Campaign(Number).Requirements.Rank <> 0 And Rank < Campaign(Number).Requirements.Rank Then
640             If .Faccion.RoyalArmy > 0 Then
650                 sErrorMsg = "{1011} Necesitas ser: " & IIf(.Genero = eGenero.Hombre, TitulosReal(Campaign(Number).Requirements.Rank).NombreBoy, TitulosReal(Campaign(Number).Requirements.Rank).NombreGirl)    'La misión no es para tu rango de facción.
660             ElseIf .Faccion.CaosArmy > 0 Then
670                 sErrorMsg = "{1011} Necesitas ser: " & IIf(.Genero = eGenero.Hombre, TitulosCaos(Campaign(Number).Requirements.Rank).NombreBoy, TitulosCaos(Campaign(Number).Requirements.Rank).NombreGirl)    'La misión no es para tu rango de facción.
680             End If
690             Exit Function
700         End If

710         If Not Campaign(Number).Properties.Redoable Then
720             If HasDoneThisCampaign(UserIndex, Number) Then
730                 sErrorMsg = Campaign(Number).Properties.Name & " {1012}"    ' no se puede repetir.
740                 Exit Function
750             End If
760         End If

770         If Campaign(Number).Rewards.Forgive > 0 Then
780             If Not .Guild Is Nothing Then
790                 If .Guild.getAlignment = eGUILD_ALIGNMENT.ALINEACION_CRIMINAL Or .Guild.getAlignment = eGUILD_ALIGNMENT.ALINEACION_LEGION Then
800                     sErrorMsg = "No puedes realizar ésta misión siendo de un clan de alineación Criminal, o Legión. Debes salir del clan."
810                     Exit Function
820                 End If
830             End If
840         End If

850         If Campaign(Number).Rewards.EnlistFaction > 0 And Faction > 0 Then
860             sErrorMsg = "No puedes realizar ésta misión debido a tu facción."
870             Exit Function
880         End If

890     End If

900     CanDoThisCampaign = True

910 End With

920 On Error GoTo 0
930 Exit Function

CanDoThisCampaign_Error:

940 Call LogError("Error " & err.Number & " (" & err.Description & ") en el procedimiento CanDoThisCampaign del módulo Módulo modCampaign en la línea: " & Erl() & " NICK: " & UserList(UserIndex).Name)

End Function

Public Function HasDoneThisCampaign(ByVal UserIndex As Integer, ByVal Number As Integer) As Boolean

'Función para saber si el usuario ya realizó la Campaña Number

Dim Current                     As Integer
Dim i                           As Long
Dim CantCampaignsDone           As Long

10  On Error GoTo HasDoneThisCampaign_Error

20  With UserList(UserIndex).Campaign

30      If Len(.CampaignsHasDone) <= 0 Then
40          HasDoneThisCampaign = False
50          Exit Function
60      End If

70      CantCampaignsDone = FieldCount(.CampaignsHasDone, 45)
80      For i = 1 To CantCampaignsDone
90          Current = val(ReadField(i, .CampaignsHasDone, 45))
100         If Current = Number Then
110             If Not Campaign(Number).Properties.Redoable Then
120                 HasDoneThisCampaign = True
130                 Exit For
140             Else
150                 HasDoneThisCampaign = False
160             End If
170         Else
180             HasDoneThisCampaign = False
190         End If
200     Next i

210 End With

220 On Error GoTo 0
230 Exit Function

HasDoneThisCampaign_Error:

240 Call LogError("Error " & err.Number & " (" & err.Description & ") procedimiento HasDoneThisCampaign Módulo modCampaign línea: " & Erl())

End Function

Public Sub AddCampaignsHasDone(ByVal UserIndex As Integer, ByVal Number As Integer)

    On Error GoTo AddCampaignsHasDone_Error

10  With UserList(UserIndex).Campaign

20      If Not HasDoneThisCampaign(UserIndex, Number) Then    'Parcheo por las redoables

30          If StrComp(.CampaignsHasDone, vbNullString) = 0 Then
40              .CampaignsHasDone = Number
50          Else
60              .CampaignsHasDone = .CampaignsHasDone & "-" & Number
70          End If

80      End If

90  End With

    On Error GoTo 0
    Exit Sub

AddCampaignsHasDone_Error:

    Call LogError("Error " & err.Number & " (" & err.Description & ") procedimiento AddCampaignsHasDone Módulo modCampaign línea: " & Erl())

End Sub

Public Sub RightClickEvents(ByVal UserIndex As Integer, ByVal Map As Byte, ByVal x As Integer, ByVal Y As Integer)

'Eventos asociados a la acción click derecho

Dim NpcIndex                    As Integer

10  On Error GoTo RightClickEvents_Error

20  With UserList(UserIndex)

30      If (Abs(.pos.Y - Y) > RANGO_VISION_Y) Or (Abs(.pos.x - x) > RANGO_VISION_X) Then
40          Exit Sub
50      End If

60      If MapData(Map, x, Y).NpcIndex > 0 Then
70          NpcIndex = MapData(Map, x, Y).NpcIndex
80          Call SendData(SendTarget.ToPCArea, UserIndex, PrepareMessageRemoveCharDialog(NpcIndex))
90          If Distancia(NpcList(NpcIndex).pos, .pos) > 8 Then
100             Call WriteConsoleMsg(UserIndex, "{01}", FontTypeNames.FONTTYPE_INFO)
110             Exit Sub
120         End If
130         Call GiveChatOverHead(UserIndex, NpcIndex)
140     End If

150 End With

160 On Error GoTo 0
170 Exit Sub

RightClickEvents_Error:

180 Call LogError("Error " & err.Number & " Descripción: & (" & err.Description & ") del procedimiento RightClickEvents del Módulo mod_Campaing" & " En la linea: " & Erl)

End Sub

Public Sub GiveChatOverHead(ByVal UserIndex As Integer, ByVal NpcIndex As Integer)

'Encuentra un chat para mostrar sobre el Npc

Dim Text                        As String

10  On Error GoTo GiveChatOverHead_Error

20  With UserList(UserIndex).Campaign

30      If .Current > 0 Then

            Dim i               As Integer

40          If Not .WaitingReward Then
50              For i = 1 To Campaign(.Current).Properties.NumStages

60                  If Campaign(.Current).Stages(i).Objetives.TargetNPC.Index = NpcList(NpcIndex).ID Then

70                      If Not .Stages(i).Done Then
80                          If Campaign(.Current).Stages(i).Properties.StageRequired > 0 Then
90                              If .Stages(Campaign(.Current).Stages(i).Properties.StageRequired).Done Then
100                                 Text = Campaign(.Current).Stages(i).Properties.Dialog.FirstTalk
110                             Else
120                                 Text = Campaign(.Current).Stages(i).Properties.Description
130                             End If
140                         Else
150                             Text = Campaign(.Current).Stages(i).Properties.Dialog.SecondTalk
160                         End If
170                         Exit For
180                     Else
190                         If .WaitingReward Then    '@ Está esperando recompensa?
200                             Text = Campaign(.Current).Stages(i).Properties.Dialog.FourthTalk
210                         Else
220                             Text = Campaign(.Current).Stages(i).Properties.Dialog.ThirdTalk
230                         End If
240                     End If
250                 End If
260             Next i
270         Else
280             If UserList(UserIndex).flags.TargetNPC > 0 Then
290                 If .NpcIndexGiver = NpcList(UserList(UserIndex).flags.TargetNPC).ID Then    'If UserList(UserIndex).flags.TargetNPC > 0 Then
300                     If UserList(UserIndex).Campaign.WaitingReward Then
310                         Call FinishCompletedCampaign(UserIndex, UserList(UserIndex).flags.TargetNPC)
320                     End If
330                 Else
340                     Call WriteConsoleMsg(UserIndex, "Para terminar la misión, debes hacer clic en la criatura que te dió inicialmente la misma.", FontTypeNames.FONTTYPE_CAMPAIGN)
350                 End If
360             End If
370         End If

390     ElseIf Len(NpcList(NpcIndex).CampaignsGiven) > 0 Then
400         Text = CampaignNpcChat(UserIndex, NpcIndex, .Current)
410     End If

420 End With

430 If Len(Text) > 0 Then
440     Call ShowCampaignChat(UserIndex, NpcIndex, Text)
450 End If

460 On Error GoTo 0
470 Exit Sub

GiveChatOverHead_Error:

480 Call LogError("Error " & err.Number & " Descripción: & (" & err.Description & ") del procedimiento GiveChatOverHead del Módulo mod_Campaing" & " En la linea: " & Erl)

End Sub

Public Function CampaignNpcChat(ByVal UserIndex As Integer, ByVal NpcIndex As Integer, ByVal CampaignNumber As Integer) As String

Dim Number                      As Integer
Dim iCantQuest                  As Integer
Dim i                           As Long
Dim sErrorMsg                   As String
Dim sFinalMsg                   As String

    On Error GoTo CampaignNpcChat_Error

10  With UserList(UserIndex).Campaign

20      If CampaignNumber = 0 Then

30          iCantQuest = FieldCount(NpcList(NpcIndex).CampaignsGiven, 45)

40          For i = 1 To iCantQuest
50              Number = val(ReadField(i, NpcList(NpcIndex).CampaignsGiven, 45))

60              If Not CanDoThisCampaign(UserIndex, Number, sErrorMsg) Then
70                  sFinalMsg = sFinalMsg & vbCrLf & sErrorMsg
80                  Number = -1
90                  .CanViewCampaignList = False
                    ' Call WriteConsoleMsg(UserIndex, sErrorMsg, FontTypeNames.FONTTYPE_CAMPAIGN)
100             Else
110                 If HasDoneThisCampaign(UserIndex, Number) Then
120                     If i = iCantQuest Then
130                         CampaignNpcChat = "Hola aventurero. Ya no dispongo de nuevas misiones para ti. Si deseas repetir alguna escribe /LISTAQUEST"
140                         .OffererNpcIndex = NpcIndex
150                         .CanViewCampaignList = True
160                         Exit Function
170                     End If

                        'Exit For
180                 Else
190                     .CanViewCampaignList = True
200                     Exit For
210                 End If
220             End If
230         Next i

240         If Number <= 0 Then
                'CampaignNpcChat = NpcList(NpcIndex).desc
250             .CanDoThisOne = 0
260             .OffererNpcIndex = 0
270         Else
280             CampaignNpcChat = Campaign(Number).Properties.Dialog.FirstTalk
290             .CanDoThisOne = Number
300             .OffererNpcIndex = NpcIndex
310         End If

320         If Len(sFinalMsg) > 0 Then
330             Call WriteConsoleMsg(UserIndex, sFinalMsg, FontTypeNames.FONTTYPE_CAMPAIGN)
340         End If

350         Exit Function
360     End If

370     If .NpcIndexGiver = NpcList(NpcIndex).ID Then
380         If .Current > 0 Then
390             If Not .WaitingReward Then
400                 CampaignNpcChat = Campaign(CampaignNumber).Properties.Dialog.ThirdTalk
410             Else
420                 CampaignNpcChat = Campaign(CampaignNumber).Properties.Dialog.FourthTalk
                    'Call FinishCompletedCampaign(UserIndex, UserList(UserIndex).flags.TargetNPC)
430             End If
440         End If
450     End If

460 End With

    On Error GoTo 0
    Exit Function

CampaignNpcChat_Error:

    Call LogError("Error " & err.Number & " (" & err.Description & ") procedimiento CampaignNpcChat Módulo modCampaign línea: " & Erl())

End Function

Public Function CampaignDblClickEvents(ByVal UserIndex As Integer, ByVal NpcIndex As Integer) As Boolean

Dim i                           As Integer
Dim HaveCampaign                As String

10  On Error GoTo CampaignDblClickEvents_Error

20  With UserList(UserIndex)

30      If .flags.Muerto <> 0 Then
40          Call WriteConsoleMsg(UserIndex, "{1330}", FontTypeNames.FONTTYPE_INFO)    '¡Estás muerto!
50          CampaignDblClickEvents = False
60          Exit Function
70      End If

80      If Distancia(.pos, NpcList(NpcIndex).pos) > 8 Then
90          Call WriteConsoleMsg(UserIndex, "{04}", FontTypeNames.FONTTYPE_INFO)    'Estás demasiado lejos.
100         CampaignDblClickEvents = False
110         Exit Function
120     End If

130     With .Campaign
140         If .CanDoThisOne > 0 Then
150             If .CanViewCampaignList And .OffererNpcIndex = NpcIndex Then
160                 Call WriteGiveCampaignList(UserIndex, .OffererNpcIndex)
170                 CampaignDblClickEvents = True
180                 Exit Function
190             ElseIf .Current > 0 Then
200                 For i = 1 To Campaign(.Current).Properties.NumStages
210                     If Not .Stages(i).Done Then
220                         If Campaign(.Current).Stages(i).Objetives.TargetNPC.Index = NpcList(NpcIndex).ID Then
230                             Call CampaignNpcDblClickEvents(UserIndex, NpcIndex)
240                             CampaignDblClickEvents = True
250                             Exit Function
260                         End If
270                     End If
280                 Next i
290             Else
300                 HaveCampaign = WhichOnes(UserIndex, NpcIndex)
                    'Si quieres conseguir una misión, ve con los personajes que tienen un signo de pregunta sobre su cabeza y haz DOBLE CLIC 'DERECHO' sobre él.
310                 If Len(HaveCampaign) > 0 Then
320                     Call WriteConsoleMsg(UserIndex, "{1014}", FontTypeNames.FONTTYPE_CAMPAIGN)    'Si quieres conseguir una misión, ve con los personajes que tienen un signo de pregunta sobre su cabeza y haz DOBLE CLIC 'DERECHO' sobre él.
330                     CampaignDblClickEvents = False
340                 Else
350                     CampaignDblClickEvents = True
360                 End If
370             End If
380         ElseIf .Current > 0 Then
390             CampaignDblClickEvents = CampaignNpcDblClickEvents(UserIndex, NpcIndex)
400         End If
410     End With
420 End With

430 'CampaignDblClickEvents = False

440 On Error GoTo 0
450 Exit Function

CampaignDblClickEvents_Error:

460 Call LogError("Error " & err.Number & " Descripción: & (" & err.Description & ") del procedimiento CampaignDblClickEvents del Módulo mod_Campaing" & " En la linea: " & Erl)

End Function

Public Function CampaignNpcDblClickEvents(ByVal UserIndex As Integer, ByVal NpcIndex As Integer) As Boolean

Dim i                           As Integer

10  On Error GoTo CampaignNpcDblClickEvents_Error

20  With UserList(UserIndex).Campaign
30      For i = 1 To Campaign(.Current).Properties.NumStages    '@ Recorro las posibilidades con un for.
40          If Not .Stages(i).Done Then
50              If Campaign(.Current).Stages(i).Objetives.TargetNPC.Index = NpcList(NpcIndex).ID Then

60                  Select Case Campaign(.Current).Stages(i).Objetives.TargetNPC.Action

                        Case eCampaingActions.Hablar

70                          If AccomplishObjetive(UserIndex, i) Then
80                              CampaignNpcDblClickEvents = True
90                          Else
100                             CampaignNpcDblClickEvents = False
110                             Exit For
120                         End If

130                         Exit For

140                     Case eCampaingActions.EntregarObj    'Entregar Obj

150                         If Not .Stages(i).ObjDelivered Then
160                             CampaignNpcDblClickEvents = DeliverCampaignObj(UserIndex)
170                         End If

180                         Exit For

190                     Case eCampaingActions.Encontrar    'Encontrar

200                         If AccomplishObjetive(UserIndex, i) Then
                                'Listo
210                             CampaignNpcDblClickEvents = True
220                         Else
230                             CampaignNpcDblClickEvents = False
240                         End If

250                         Exit For

260                     Case eCampaingActions.KeyWord    'Decir Keyword
270                         If Campaign(.Current).Stages(i).Properties.StageRequired > 0 Then
280                             If Not .Stages(Campaign(.Current).Stages(i).Properties.StageRequired).Done Then
290                                 Call WriteConsoleMsg(UserIndex, "Para realizar el objetivo '" & Campaign(.Current).Stages(i).Properties.Description & "' primero debes '" & Campaign(.Current).Stages(Campaign(.Current).Stages(i).Properties.StageRequired).Properties.Description & "'", FontTypeNames.FONTTYPE_CAMPAIGN)
300                                 CampaignNpcDblClickEvents = False
310                             Else
320                                 Call WriteRequestKeyword(UserIndex)
330                                 CampaignNpcDblClickEvents = True
340                             End If
350                         End If

360                         Exit For
370                 End Select
380             End If
390         End If
400     Next i
410 End With

420 On Error GoTo 0
430 Exit Function

CampaignNpcDblClickEvents_Error:

440 Call LogError("Error " & err.Number & " (" & err.Description & ") procedimiento CampaignNpcDblClickEvents Módulo modCampaign línea: " & Erl())

End Function

Public Function DeliverObjects(ByVal UserIndex As Integer, ByVal NpcIndex As Integer, ByVal tCurrentStage As Integer)

Dim objIndex                    As Integer
Dim ObjAmount                   As Integer
Dim Text                        As String

10  On Error GoTo DeliverObjects_Error

20  With UserList(UserIndex).Campaign

30      ObjAmount = Campaign(.Current).Stages(tCurrentStage).Objetives.TargetObj.amount
40      objIndex = Campaign(.Current).Stages(tCurrentStage).Objetives.TargetObj.objIndex

50      If TieneObjetos(objIndex, ObjAmount, UserIndex) Then
60          Text = Campaign(.Current).Stages(tCurrentStage).Properties.Dialog.SecondTalk
70          Call ShowCampaignChat(UserIndex, NpcIndex, Text)
80          Call QuitarObjetos(objIndex, ObjAmount, UserIndex)
90          Call AccomplishObjetive(UserIndex, tCurrentStage)
100         Call WriteConsoleMsg(UserIndex, "¡Excelente! Has entregado los ítems del objetivo " & Campaign(.Current).Stages(tCurrentStage).Properties.Description & " de la misión.", FontTypeNames.FONTTYPE_CAMPAIGN)
110         .Stages(tCurrentStage).ObjDelivered = True

            '@ Si completó todos los objetivos, entonces podemos solicitar recompensa.
120         If .StagesCompleted = Campaign(.Current).Properties.NumStages Then
130             .WaitingReward = True
140         End If
150     Else
160         If Campaign(.Current).Stages(tCurrentStage).Objetives.TargetObj.objIndex > 0 Then
170             Call WriteConsoleMsg(UserIndex, "Te faltan " & ObjData(Campaign(.Current).Stages(tCurrentStage).Objetives.TargetObj.objIndex).Name & " " & Campaign(.Current).Stages(tCurrentStage).Properties.Description & " de la misión.", FontTypeNames.FONTTYPE_CAMPAIGN)
180         End If
190         .Stages(tCurrentStage).Done = False
200         Text = Campaign(.Current).Stages(tCurrentStage).Properties.Dialog.ThirdTalk
210         Call ShowCampaignChat(UserIndex, NpcIndex, Text)
220     End If

230 End With

240 On Error GoTo 0
250 Exit Function

DeliverObjects_Error:

260 Call LogError("Error " & err.Number & " (" & err.Description & ") procedimiento DeliverObjects Módulo modCampaign línea: " & Erl())

End Function

Public Sub CampaignBegin(ByVal UserIndex As Integer)

Dim i                           As Integer
Dim iTargetNpc                  As Integer
Dim Text                        As String

10  On Error GoTo CampaignBegin_Error

20  iTargetNpc = UserList(UserIndex).flags.TargetNPC

30  With UserList(UserIndex).Campaign

40      .Current = .CanDoThisOne
        '.CurrentStage = 1
50      .WaitingReward = False

60      If .Current > 0 Then

70          ReDim .Stages(1 To (Campaign(.Current).Properties.NumStages)) As UserStagesCampaign

80          If .OffererNpcIndex <> 0 Then
90              .NpcIndexGiver = NpcList(.OffererNpcIndex).ID
100         Else
110             Call FinishUncompletedCampaign(UserIndex, CampaignFailReason.Leave)
120             Exit Sub
130         End If             'Falto esto

140         .Timing = 0
150         .CanDoThisOne = 0
160         .OffererNpcIndex = 0
170         .CanViewCampaignList = False

180         For i = 1 To Campaign(.Current).Properties.NumStages
                '                If i = 1 Then
                '                    Call GiveStageObj(UserIndex, i)
                '                End If
190             .Stages(i).Done = False
200             .Stages(i).StageTiming = 0    'Campaign(.Current).Stages(i).Properties.Timing
           
210             .Stages(i).AmountTarget = 0 'NUEVO!
                '.Stages(i).AmountTargetNpc = 0
                '.Stages(i).AmountTargetUser = 0
                '.Stages(i).AmountTargetObj = 0
               
             .Stages(i).HaveToFoundPlace = (val(Campaign(.Current).Stages(i).Objetives.TargetLocation.Trigger) <> 0 Or (val(Campaign(.Current).Stages(i).Objetives.TargetLocation.posX) <> 0 And val(Campaign(.Current).Stages(i).Objetives.TargetLocation.posY) <> 0 And val(Campaign(.Current).Stages(i).Objetives.TargetLocation.Map)) <> 0)
                '.Stages(i).HaveToFoundPlace = 0 'Testeamos algo '@ Esto estaba MUY MAL.

                '                If Campaign(.Current).Stages(i).Objetives.TargetNPC.Action = 0 And Campaign(.Current).Stages(i).Objetives.TargetObj.objIndex > 0 Then
                '                    If TieneObjetos(Campaign(.Current).Stages(i).Objetives.TargetObj.objIndex, Campaign(.Current).Stages(i).Objetives.TargetObj.amount, UserIndex) Then
                '                        Call AccomplishObjetive(UserIndex, i)
                '                    End If
                '                End If
250         Next i

260         Text = Campaign(.Current).Properties.Dialog.SecondTalk

270         Call WriteConsoleMsg(UserIndex, "{997}", FontTypeNames.FONTTYPE_CAMPAIGN)    'Has aceptado la misión
280         Call WriteConsoleMsg(UserIndex, "{998}", FontTypeNames.FONTTYPE_CAMPAIGN)    'Escribe /INFOQUEST para ver los detalles de la misma.
290         Call WriteToggleCampaignState(UserIndex)

300         If UserList(UserIndex).flags.TargetNPC > 0 Then
310             Call ShowCampaignChat(UserIndex, UserList(UserIndex).flags.TargetNPC, Text)
320         Else
330             Call FinishUncompletedCampaign(UserIndex, CampaignFailReason.Leave)    ' Call ShowCampaignChat(UserIndex, .NpcIndexGiver, Text)
340         End If
350     Else
360         Call WriteConsoleMsg(UserIndex, "Misión cancelada.", FontTypeNames.FONTTYPE_CAMPAIGN)
370     End If
380 End With

390 On Error GoTo 0
400 Exit Sub

CampaignBegin_Error:

410 Call LogError("Error " & err.Number & " (" & err.Description & ") procedimiento CampaignBegin Módulo modCampaign línea: " & Erl())

End Sub

Public Sub CampaignTime(ByVal UserIndex As Integer)

    On Error GoTo CampaignTime_Error

20  With UserList(UserIndex).Campaign

30      If .Current > 0 And UserList(UserIndex).flags.UserLogged And UserList(UserIndex).ConnIDValida And Len(UserList(UserIndex).Name) > 0 Then
40          If Campaign(.Current).Properties.Timing > 0 Then
                '@ Tiempo de la misión en general.
50              If Not .WaitingReward Then
60                  .Timing = .Timing + 1
70                  If .Timing >= Campaign(.Current).Properties.Timing Then
80                      Call FinishUncompletedCampaign(UserIndex, CampaignFailReason.Timing)
90                  End If
100             End If
110         End If

            Dim i               As Integer
120         For i = 1 To Campaign(.Current).Properties.NumStages
                '@ Tiempo del objetivo actual.

                '@ Acá en teoría, debería consultar si la única misión que queda por hacer, tiene tiempo Pero eso también hay que datearlo de esa forma, sino el tiempo de la misión nunca va a funcionar si una misión tiene 3 objetivos totales, y 2 de ellas tienen tiempo.
130             If val(Campaign(.Current).Stages(i).Properties.Timing) > 0 Then
140                 If Not .Stages(i).Done Then
150                     .Stages(i).StageTiming = .Stages(i).StageTiming + 1
160                     If val(.Stages(i).StageTiming) >= val(Campaign(.Current).Stages(i).Properties.Timing) Then
170                         Call ReloadStageTimed(UserIndex)
180                     End If

190                     If val(Campaign(.Current).Stages(i).Properties.Timing) > 60 Then
200                         If .Stages(i).StageTiming Mod 60 = 0 Then
210                             Call WriteConsoleMsg(UserIndex, "Tienes " & Round((val(Campaign(.Current).Stages(i).Properties.Timing) - .Stages(i).StageTiming) / 60, 0) & " minutos restantes para completar el objetivo.", FontTypeNames.FONTTYPE_CAMPAIGN)
220                         End If
230                     End If
240                     Exit For    '@ Cerramos el bucle.
250                 End If
260             End If
270         Next i
280     End If

290 End With

    On Error GoTo 0
    Exit Sub

CampaignTime_Error:

    Call LogError("Error " & err.Number & " (" & err.Description & ") procedimiento CampaignTime Módulo modCampaign línea: " & Erl())

End Sub

Public Sub FinishUncompletedCampaign(ByVal UserIndex As Integer, ByVal Reason As Byte)

    On Error GoTo FinishUncompletedCampaign_Error

10  Call ResetCampaignTempData(UserIndex)
20  Call WriteCloseCampaignForms(UserIndex)

30  Select Case Reason
        Case CampaignFailReason.Leave
40          Call WriteConsoleMsg(UserIndex, "{1003}", FontTypeNames.FONTTYPE_CAMPAIGN)    '¡Has abandonado la misión!

50      Case CampaignFailReason.Reject
60          Call WriteConsoleMsg(UserIndex, "{1002}", FontTypeNames.FONTTYPE_ADMIN)    '¡Has rechazado la misión!

70      Case CampaignFailReason.Death
80          Call WriteConsoleMsg(UserIndex, "{1001}", FontTypeNames.FONTTYPE_CAMPAIGN)    '¡Has muerto en una misión!
90          Call WriteConsoleMsg(UserIndex, "{1000}", FontTypeNames.FONTTYPE_CAMPAIGN)    '¡No has podido terminar la misión!

100     Case CampaignFailReason.Timing
110         Call WriteConsoleMsg(UserIndex, "{999}", FontTypeNames.FONTTYPE_CAMPAIGN)    '¡Se ha agotado el tiempo para cumplir el objetivo!
120         Call WriteConsoleMsg(UserIndex, "{1000}", FontTypeNames.FONTTYPE_CAMPAIGN)    '¡No has podido terminar la misión!

130 End Select

140 Call WriteToggleCampaignState(UserIndex)

    On Error GoTo 0
    Exit Sub

FinishUncompletedCampaign_Error:

    Call LogError("Error " & err.Number & " (" & err.Description & ") procedimiento FinishUncompletedCampaign Módulo modCampaign línea: " & Erl())

End Sub

Public Sub ResetCampaignTempData(ByVal UserIndex As Integer)

Dim i                           As Integer

    On Error GoTo ResetCampaignTempData_Error

10  With UserList(UserIndex).Campaign

20      If .Current > 0 Then

            '.CurrentStage = 0
30          .StagesCompleted = 0
40          .WaitingReward = False
50          .NpcIndexGiver = 0
60          .Timing = 0
70          .CanDoThisOne = 0
80          .OffererNpcIndex = 0
90          .CanViewCampaignList = False

100         For i = 1 To Campaign(.Current).Properties.NumStages
110             .Stages(i).StageTiming = 0
120             .Stages(i).AmountTarget = 0 'NUEVO!
'120             .Stages(i).AmountTargetNpc = 0
'130             .Stages(i).AmountTargetUser = 0
'140             .Stages(i).AmountTargetObj = 0
150             .Stages(i).HaveToFoundPlace = False
160             .Stages(i).Done = False
170             .Stages(i).ObjDelivered = False
180         Next i

190         .Current = 0
200     End If
210 End With

    On Error GoTo 0
    Exit Sub

ResetCampaignTempData_Error:

    Call LogError("Error " & err.Number & " (" & err.Description & ") procedimiento ResetCampaignTempData Módulo modCampaign línea: " & Erl())

End Sub

Public Sub ResetCampaignAllData(ByVal UserIndex As Integer)

Dim i                           As Integer

    On Error GoTo ResetCampaignAllData_Error

10  With UserList(UserIndex).Campaign

        '.CurrentStage = 0
20      .StagesCompleted = 0
30      .WaitingReward = False
40      .NpcIndexGiver = 0
50      .Timing = 0

60      If .Current > 0 Then
70          For i = 1 To Campaign(.Current).Properties.NumStages
80              .Stages(i).StageTiming = 0
90              .Stages(i).AmountTarget = 0 'NUEVO!
'90              .Stages(i).AmountTargetNpc = 0
'100             .Stages(i).AmountTargetUser = 0
'110             .Stages(i).AmountTargetObj = 0
120             .Stages(i).HaveToFoundPlace = False
130             .Stages(i).Done = False
140             .Stages(i).ObjDelivered = False
150         Next i
160     End If

170     .CanDoThisOne = 0
180     .OffererNpcIndex = 0
190     .CanViewCampaignList = False
200     .CampaignsHasDone = vbNullString
210     .Current = 0
220 End With

    On Error GoTo 0
    Exit Sub

ResetCampaignAllData_Error:

    Call LogError("Error " & err.Number & " (" & err.Description & ") procedimiento ResetCampaignAllData Módulo modCampaign línea: " & Erl())

End Sub

Function AddPointer(ByRef LastPointer As Integer) As Integer
    LastPointer = LastPointer + 1
    AddPointer = LastPointer
End Function

Public Sub LoadUserCampaignData(ByVal UserIndex As Integer, Data As String)

Dim LastPoint                   As Integer

    On Error GoTo LoadUserCampaignData_Error

10  If Not StrComp(Data, vbNullString) = 0 Then    'About
20      With UserList(UserIndex).Campaign
            'Ejemplo: 19-0-218-0-19-0-0-0-0-0-14-0-0-0-0-0-0-1-0-0-0-0-0-0-0-0-0-0-0
30          .Current = val(ReadField(AddPointer(LastPoint), Data, 45)) '19
40          .WaitingReward = IIf(val(ReadField(AddPointer(LastPoint), Data, 45)), True, False) '0
50          .NpcIndexGiver = val(ReadField(AddPointer(LastPoint), Data, 45)) '218
60          .Timing = val(ReadField(AddPointer(LastPoint), Data, 45))

70          .CanDoThisOne = val(ReadField(AddPointer(LastPoint), Data, 45))
80          .OffererNpcIndex = val(ReadField(AddPointer(LastPoint), Data, 45))
90          .CanViewCampaignList = IIf(val(ReadField(AddPointer(LastPoint), Data, 45)) <> 0, True, False)
100         .StagesCompleted = val(ReadField(AddPointer(LastPoint), Data, 45))
           
110         If .Current > 0 Then
120             .CanDoThisOne = .Current

                Dim i           As Integer

130             ReDim .Stages(1 To Campaign(.Current).Properties.NumStages)
               
140             For i = 1 To Campaign(.Current).Properties.NumStages
150                 .Stages(i).Done = IIf(val(ReadField(AddPointer(LastPoint), Data, 45)) <> 0, True, False)
160                 .Stages(i).StageTiming = val(ReadField(AddPointer(LastPoint), Data, 45))
170                 .Stages(i).AmountTarget = val(ReadField(AddPointer(LastPoint), Data, 45)) 'NUEVO!
'170                 .Stages(i).AmountTargetNpc = val(ReadField(AddPointer(LastPoint), DATA, 45))
'180                 .Stages(i).AmountTargetUser = val(ReadField(AddPointer(LastPoint), DATA, 45))
'190                 .Stages(i).AmountTargetObj = val(ReadField(AddPointer(LastPoint), DATA, 45))
200                 .Stages(i).HaveToFoundPlace = IIf(val(ReadField(AddPointer(LastPoint), Data, 45)) <> 0, True, False)
210                 .Stages(i).ObjDelivered = IIf(val(ReadField(AddPointer(LastPoint), Data, 45)) <> 0, True, False)
220             Next i
230         End If

            'Debug.Print "Load Campaing Field counts: " & FieldCount(data, 45) & " must Be: " & (Campaign(UserList(UserIndex).Campaign.Current).Properties.NumStages * 6) + 8
240     End With
250 End If

    On Error GoTo 0
    Exit Sub

LoadUserCampaignData_Error:

    Call LogError("Error " & err.Number & " (" & err.Description & ") procedimiento LoadUserCampaignData Módulo modCampaign línea: " & Erl())

End Sub

Public Function SaveCampaignData(ByVal UserIndex As Integer) As clsFastString

10  On Error GoTo SaveCampaignData_Error

20  Set SaveCampaignData = New clsFastString

30  With UserList(UserIndex)
40      If .Campaign.Current > 0 Then
50          If Campaign(.Campaign.Current).Properties.FinishWhenDisconnect Then
60              SaveCampaignData.Clear
70              SaveCampaignData = SaveCampaignData.Value    'vbNullString
80          Else
90              With UserList(UserIndex).Campaign
                    'Dim finalString As String

100                 SaveCampaignData.Append CStr(.Current)
110                 SaveCampaignData.Append "-" & CStr(IIf(.WaitingReward, 1, 0))
120                 SaveCampaignData.Append "-" & CStr(.NpcIndexGiver)
130                 SaveCampaignData.Append "-" & CStr(.Timing)
140                 SaveCampaignData.Append "-" & CStr(.CanDoThisOne)
150                 SaveCampaignData.Append "-" & CStr(.OffererNpcIndex)
160                 SaveCampaignData.Append "-" & CStr(IIf(val(.CanViewCampaignList), 1, 0))
170                 SaveCampaignData.Append "-" & CStr(.StagesCompleted)

                    '8 strings

180                 If .Current > 0 Then
                        Dim i     As Integer

190                     For i = 1 To Campaign(.Current).Properties.NumStages

200                         SaveCampaignData.Append "-" & CStr(IIf(.Stages(i).Done, 1, 0))
210                         SaveCampaignData.Append "-" & CStr(.Stages(i).StageTiming)
220                         SaveCampaignData.Append "-" & CStr(.Stages(i).AmountTarget)

                            '190                         SaveCampaignData.Append "-" & CStr(.Stages(i).AmountTargetNpc)
                            '200                         SaveCampaignData.Append "-" & CStr(.Stages(i).AmountTargetUser)
                            '210                         SaveCampaignData.Append "-" & CStr(.Stages(i).AmountTargetObj)
230                         SaveCampaignData.Append "-" & CStr(IIf(.Stages(i).HaveToFoundPlace, 1, 0))
240                         SaveCampaignData.Append "-" & CStr(IIf(.Stages(i).ObjDelivered, 1, 0))
                            '6 strings por cada STAGE
250                     Next i
260                 End If

270             End With
280         End If
290     Else
300         SaveCampaignData.Clear
310         .Campaign.CampaignUnfinishSaved = SaveCampaignData.Value
320     End If

        'Debug.Print "SAVE Campaing Field counts: " & FieldCount(finalString, 45) & " must Be: " & (Campaign(UserList(UserIndex).Campaign.Current).Properties.NumStages * 6) + 8
330     .Campaign.CampaignUnfinishSaved = SaveCampaignData.Value

340 End With

350 On Error GoTo 0
360 Exit Function

SaveCampaignData_Error:

370 Call LogError("Error " & err.Number & " (" & err.Description & ") procedimiento SaveCampaignData Módulo modCampaign línea: " & Erl())

End Function

Public Sub ReloadStageTimed(ByVal UserIndex As Integer)

Dim i                           As Integer

    On Error GoTo ReloadStageTimed_Error

10  With UserList(UserIndex).Campaign

20      For i = 1 To Campaign(.Current).Properties.NumStages
30          If Not .Stages(i).Done And .Stages(i).StageTiming > 0 Then
40              .Stages(i).StageTiming = 0
50              .Stages(i).AmountTarget = 0 'NUEVO! 21/12/2020
'50              .Stages(i).AmountTargetNpc = 0
'60              .Stages(i).AmountTargetUser = 0
'70              .Stages(i).AmountTargetObj = 0
80              .Stages(i).ObjDelivered = False
90              .Stages(i).HaveToFoundPlace = val(Campaign(.Current).Stages(i).Objetives.TargetLocation.Trigger <> 0) Or (val(Campaign(.Current).Stages(i).Objetives.TargetLocation.posX <> 0) And val(Campaign(.Current).Stages(i).Objetives.TargetLocation.posY <> 0) And val(Campaign(.Current).Stages(i).Objetives.TargetLocation.Map <> 0))
100         End If
110     Next i

120     Call WriteConsoleMsg(UserIndex, "{999} Se ha reiniciado el objetivo.", FontTypeNames.FONTTYPE_CAMPAIGN)    '¡Se ha agotado el tiempo para cumplir el objetivo!
130     Call WriteUpdateCampaignInfo(UserIndex, .Current)

140 End With

    On Error GoTo 0
    Exit Sub

ReloadStageTimed_Error:

    Call LogError("Error " & err.Number & " (" & err.Description & ") procedimiento ReloadStageTimed Módulo modCampaign línea: " & Erl())

End Sub
Tengo uno recontra mil mejorado pero está muy adaptado a Bender.

Deberías laburar mucho en todo lo que es protocolo y eso, pero bueno, te lo dejo por si te sirve, porque es basado justamente en este que pedís:
Ave About !
 

Ameynar AO2

Extraidor De Sistemas LVL 5
Codigo modCampaings:
Option Explicit

Public Sub LoadCampaigns()

Dim tDesc                       As Boolean
Dim i                           As Long
Dim S                           As Long
Dim LoopA                       As Long
Dim LoopB                       As Long
Dim tRecompensa                 As New clsFastString
Dim Leer                        As New clsIniReader

10  On Error GoTo ErrHandler

20  Call WriteToConsole("Cargando campañas...")
    '    If frmCargando.Visible Then
    '        'frmCargando.Label1(2).Caption = "Cargando Campaings.AO"
    '    End If

30  If FileExist(DatPath & "Campaigns.AO", vbNormal) Then

        '/////////////////////////////////////////READ//BEGIN//////////////////////////////////////////////

40      Call Leer.Initialize(DatPath & "Campaigns.AO")

50      Set LeerCampaigns = Leer

60      NumCampaigns = val(Leer.GetValue("INIT", "NumCampaigns"))

70      ReDim Campaign(1 To NumCampaigns) As Campaign

80      For i = 1 To NumCampaigns

90          With Campaign(i)

                '////////////////////////////////////////READ//PROPERTIES//////////////////////////////////////////

100             With .Properties
110                 .Name = Leer.GetValue("Campaign" & i, "Name")
                    '            .Description = Leer.GetValue("Campaign" & i, "Description")    'Cambio de lugar la descripción, así podemos cargarla automáticamente.
                    '            .Description = .Description &  ")" 'Cierro el paréntesis aca.
120                 .Dialog.FirstTalk = Leer.GetValue("Campaign" & i, "Dialog1")
130                 .Dialog.SecondTalk = Leer.GetValue("Campaign" & i, "Dialog2")
140                 .Dialog.ThirdTalk = Leer.GetValue("Campaign" & i, "Dialog3")
150                 .Dialog.FourthTalk = Leer.GetValue("Campaign" & i, "Dialog4")
160                 .Dialog.FifthTalk = Leer.GetValue("Campaign" & i, "Dialog5")
170                 .NumStages = val(Leer.GetValue("Campaign" & i, "NumStages"))
180                 .Redoable = IIf(val(Leer.GetValue("Campaign" & i, "Redoable")) <> 0, True, False)
190                 .Timing = val(Leer.GetValue("Campaign" & i, "Time"))
200                 .FinishWhenDie = val(Leer.GetValue("Campaign" & i, "FinishWhenDie"))
210                 .FinishWhenDisconnect = val(Leer.GetValue("Campaign" & i, "FinishWhenDisconnect"))
220             End With

                '////////////////////////////////////////READ//REQUIREMENTS////////////////////////////////////////

230             With .Requirements
240                 .MinLvl = val(Leer.GetValue("Campaign" & i, "MinLvl"))
250                 .MaxLvl = val(Leer.GetValue("Campaign" & i, "MaxLvl"))
260                 .PreviousCampaign = val(Leer.GetValue("Campaign" & i, "PreviousCampaign"))
270                 .Class = val(Leer.GetValue("Campaign" & i, "Class"))
280                 .Race = val(Leer.GetValue("Campaign" & i, "Race"))
290                 .Genre = val(Leer.GetValue("Campaign" & i, "Genre"))
300                 .Alignment = val(Leer.GetValue("Campaign" & i, "Alignment"))
310                 .Faction = val(Leer.GetValue("Campaign" & i, "FACTION"))
320                 .Rank = val(Leer.GetValue("Campaign" & i, "Rank"))
330                 If .MinLvl > .MaxLvl And .MaxLvl > 0 Then .MinLvl = .MaxLvl

340             End With

                '/////////////////////////////////////////READ//REWARDS////////////////////////////////////////////

350             With .Rewards
360                 .PlateCoins = val(Leer.GetValue("Campaign" & i, "PlateCoins"))
370                 .EnlistFaction = val(Leer.GetValue("Campaign" & i, "EnlistFaction"))    '0 = Nada, 1 Armada, 2 Caos
380                 .Forgive = val(Leer.GetValue("Campaign" & i, "Forgive"))    'Perdon a los PKS!
390                 .RewardExp = val(Leer.GetValue("Campaign" & i, "RewardExp"))
400                 .RewardGold = val(Leer.GetValue("Campaign" & i, "RewardGold"))
410                 .NumRewardObj = val(Leer.GetValue("Campaign" & i, "NumRewardObj"))

420                 .RewardByClass = val(Leer.GetValue("Campaign" & i, "RewardByClass"))
430                 .NumRewardObjByClass = val(Leer.GetValue("Campaign" & i, "NumRewardObjByClass"))    'Cantidad de premios por clase, que van a recibir TODAS las clases. Siempre es la misma cantidad de premios para todas en una misma misión.

440                 tRecompensa.Clear

450                 If Campaign(i).Properties.FinishWhenDie Then
460                     If Len(tRecompensa.Value) = 0 Then
470                         tRecompensa.Append " INFO: Ésta mision se cancela al MORIR"
480                     Else
490                         tRecompensa.Append ", INFO: ésta mision se cancela al MORIR."
500                     End If
510                 End If

520                 If Campaign(i).Properties.FinishWhenDisconnect Then
530                     If Len(tRecompensa.Value) = 0 Then
540                         tRecompensa.Append " INFO: Ésta mision se cancela al DESCONECTARSE del juego."
550                     Else
560                         tRecompensa.Append ", INFO: ésta mision se cancela al DESCONECTARSE del juego."
570                     End If
580                 End If

590                 If Campaign(i).Properties.Timing > 0 Then
600                     If Len(tRecompensa.Value) = 0 Then
610                         tRecompensa.Append " INFO: Debes realizar la misión en menos de " & IIf(Campaign(i).Properties.Timing > 60, Campaign(i).Properties.Timing / 60 & " min.", Campaign(i).Properties.Timing & " seg.")
620                     Else
630                         tRecompensa.Append ", INFO: Debes realizar la misión en menos de " & IIf(Campaign(i).Properties.Timing > 60, Campaign(i).Properties.Timing / 60 & " min.", Campaign(i).Properties.Timing & " seg.")
640                     End If
650                 End If

660                 If .RewardExp > 0 Then
670                     If Len(tRecompensa.Value) = 0 Then
680                         tRecompensa.Append "Recompensa: " & .RewardExp & " de Experiencia"
690                     Else
700                         tRecompensa.Append ", " & .RewardExp & " de Experiencia"
710                     End If
720                 End If

730                 If .RewardGold > 0 Then
740                     If Len(tRecompensa.Value) = 0 Then
750                         tRecompensa.Append "Recompensa: " & .RewardGold & " de Oro"
760                     Else
770                         tRecompensa.Append ", " & .RewardGold & " de Oro"
780                     End If
790                 End If

800                 If .Forgive = 1 Then
810                     If Len(tRecompensa.Value) = 0 Then
820                         tRecompensa.Append "Recompensa: Volverás a ser Ciudadano"
830                     Else
840                         tRecompensa.Append ", y Volverás a ser Ciudadano"
850                     End If
860                 End If

870                 Select Case .EnlistFaction
                        Case 1

880                         If Len(tRecompensa.Value) = 0 Then
890                             If BonusExpArmy > 0 Then
900                                 tRecompensa.Append "Recompensa: Enlistarse en el Ejército Real y Ganarás " & BonusExpArmy & "% más de experiencia."
910                             Else
920                                 tRecompensa.Append "Recompensa: Enlistarse en el Ejército Real."
930                             End If
940                         Else
950                             If BonusExpArmy > 0 Then
960                                 tRecompensa.Append ", Enlistarse en el Ejército Real y Ganarás " & BonusExpArmy & "% más de experiencia."
970                             Else
980                                 tRecompensa.Append ", Enlistarse en el Ejército Real"
990                             End If
1000                        End If
1010                    Case 2
1020                        If Len(tRecompensa.Value) = 0 Then
1030                            If BonusExpCaos > 0 Then
1040                                tRecompensa.Append "Recompensa: Enlistarse en la Legión Oscura y ganarás " & BonusExpCaos & "% más de experiencia"
1050                            Else
1060                                tRecompensa.Append "Recompensa: Enlistarse en la Legión Oscura."
1070                            End If
1080                        Else
1090                            If BonusExpCaos > 0 Then
1100                                tRecompensa.Append ", Recompensa: Enlistarse en la Legión Oscura y ganarás " & BonusExpCaos & "% más de experiencia"
1110                            Else
1120                                tRecompensa.Append ", Recompensa: Enlistarse en la Legión Oscura."
1130                            End If
1140                        End If
1150                    Case 3
1160                        If Len(tRecompensa.Value) = 0 Then
1170                            tRecompensa.Append "Recompensa: Ser miembro del Consejo Mercenario."
1180                        Else
1190                            tRecompensa.Append ", Ser miembro del Consejo Mercenario."
1200                        End If
1210                End Select

1220                If Not .NumRewardObj <= 0 Then

1230                    ReDim .RewardObj(1 To .NumRewardObj) As Obj

1240                    For LoopA = 1 To .NumRewardObj
1250                        .RewardObj(LoopA).objIndex = val(Leer.GetValue("Campaign" & i, "RewardObj" & LoopA & "Index"))
1260                        .RewardObj(LoopA).amount = val(Leer.GetValue("Campaign" & i, "RewardObj" & LoopA & "Amount"))

1270                        If .RewardObj(LoopA).amount > 0 Then
1280                            If Len(tRecompensa.Value) Then
1290                                tRecompensa.Append "Recompensa: " & IIf(.RewardObj(LoopA).amount > 1, .RewardObj(LoopA).amount & " ", "") & ObjData(.RewardObj(LoopA).objIndex).Name
1300                            Else
1310                                tRecompensa.Append ", " & IIf(.RewardObj(LoopA).amount > 1, .RewardObj(LoopA).amount & " ", "") & ObjData(.RewardObj(LoopA).objIndex).Name
1320                            End If
                                'Debug.Print "REcompensa: " & tRecompensa
1330                        Else
1340                            .NumRewardObj = .NumRewardObj - 1    '@ Fixiame el error automáticamente.
1350                        End If
1360                    Next LoopA

1370                Else
1380                    ReDim .RewardObj(0)
1390                End If

1400                If .NumRewardObjByClass > 0 Then
1410                    If .NumRewardObjByClass > MAX_INVENTORY_SLOTS Then .NumRewardObjByClass = MAX_INVENTORY_SLOTS    'MAX 25!!
1420                    For LoopA = 1 To NUMCLASES
1430                        For LoopB = 1 To .NumRewardObjByClass    'MAX 25!!
1440                            If val(Leer.GetValue("Campaign" & i, "Class" & LoopA & "ObjIndex" & LoopB)) > 0 Then
1450                                .RewardObjByClass(LoopA).ClassReward(LoopB).objIndex = val(Leer.GetValue("Campaign" & i, "Class" & LoopA & "ObjIndex" & LoopB))
1460                                .RewardObjByClass(LoopA).ClassReward(LoopB).amount = val(Leer.GetValue("Campaign" & i, "Class" & LoopA & "ObjAmount" & LoopB))

1470                                If .RewardObjByClass(LoopA).ClassReward(LoopB).amount > 0 Then
1480                                    If Len(.RewardObjByClass(LoopA).Description) = 0 Then
1490                                        .RewardObjByClass(LoopA).Description = "Extra: " & IIf(.RewardObjByClass(LoopA).ClassReward(LoopB).amount > 1, .RewardObjByClass(LoopA).ClassReward(LoopB).amount & " ", "") & " " & ObjData(.RewardObjByClass(LoopA).ClassReward(LoopB).objIndex).Name
1500                                    Else
1510                                        .RewardObjByClass(LoopA).Description = .RewardObjByClass(LoopA).Description & ", " & IIf(.RewardObjByClass(LoopA).ClassReward(LoopB).amount > 1, .RewardObjByClass(LoopA).ClassReward(LoopB).amount & " ", "") & ObjData(.RewardObjByClass(LoopA).ClassReward(LoopB).objIndex).Name
1520                                    End If
1530                                Else
1540                                    .NumRewardObjByClass = .NumRewardObjByClass - 1
1550                                End If
1560                            End If
1570                        Next LoopB
1580                    Next LoopA
1590                End If

1600                tRecompensa.Append " |||| "    '& tRecompensa    '@ Emprolijo un poco el cartel.

1610                .Description = Leer.GetValue("Campaign" & i, "Description")    'Añadimos la descripción junto con las recompensas de forma automáticas.
1620                .Description = .Description & tRecompensa.Value
                    '.RewardDescription = tRecompensa
1630            End With

                '/////////////////////////////////////////READ//STAGES/////////////////////////////////////////////

1640            ReDim .Stages(1 To .Properties.NumStages) As CampaignStage

1650            For S = 1 To .Properties.NumStages

1660                With .Stages(S)
1670                    With .Properties
1680                        .Description = Leer.GetValue("Campaign" & i & " - Stage" & S, "Description")
1690                        .Dialog.FirstTalk = Leer.GetValue("Campaign" & i & " - Stage" & S, "Dialog1")
1700                        .Dialog.SecondTalk = Leer.GetValue("Campaign" & i & " - Stage" & S, "Dialog2")
1710                        .Dialog.ThirdTalk = Leer.GetValue("Campaign" & i & " - Stage" & S, "Dialog3")
1720                        .Dialog.FourthTalk = ""
1730                        .Dialog.FifthTalk = ""
1740                        .Timing = val(Leer.GetValue("Campaign" & i & " - Stage" & S, "Time"))
1750                        .StageRequired = val(Leer.GetValue("Campaign" & i & " - Stage" & S, "StageRequired"))
1760                    End With

1770                    With .Objetives
1780                        .TargetNPC.Index = val(Leer.GetValue("Campaign" & i & " - Stage" & S, "TargetNpcIndex"))
1790                        .TargetNPC.amount = val(Leer.GetValue("Campaign" & i & " - Stage" & S, "TargetNpcAmount"))
1800                        .TargetNPC.Action = val(Leer.GetValue("Campaign" & i & " - Stage" & S, "TargetNpcAction"))
1810                        .TargetObj.objIndex = val(Leer.GetValue("Campaign" & i & " - Stage" & S, "TargetObjIndex"))
1820                        .TargetObj.amount = val(Leer.GetValue("Campaign" & i & " - Stage" & S, "TargetObjAmount"))
1830                        .TargetUser.MinLvl = val(Leer.GetValue("Campaign" & i & " - Stage" & S, "TargetUserMinLvl"))
1840                        .TargetUser.MaxLvl = val(Leer.GetValue("Campaign" & i & " - Stage" & S, "TargetUserMaxLvl"))
1850                        .TargetUser.amount = val(Leer.GetValue("Campaign" & i & " - Stage" & S, "TargetUserAmount"))
1860                        .TargetUser.Alignment = val(Leer.GetValue("Campaign" & i & " - Stage" & S, "TargetUserAlignment"))
1870                        .TargetUser.Faction = val(Leer.GetValue("Campaign" & i & " - Stage" & S, "TargetUserFACTION"))
1880                        .TargetUser.Rank = val(Leer.GetValue("Campaign" & i & " - Stage" & S, "TargetUserRank"))
1890                        .TargetLocation.Trigger = val(Leer.GetValue("Campaign" & i & " - Stage" & S, "TargetLocationTrigger"))
1900                        .TargetLocation.posX = val(Leer.GetValue("Campaign" & i & " - Stage" & S, "TargetLocationPosX"))
1910                        .TargetLocation.posY = val(Leer.GetValue("Campaign" & i & " - Stage" & S, "TargetLocationPosY"))
1920                        .TargetLocation.Map = val(Leer.GetValue("Campaign" & i & " - Stage" & S, "TargetLocationMap"))
1930                        .KeyWord = Leer.GetValue("Campaign" & i & " - Stage" & S, "KeyWord")
1940                    End With

1950                    .NumGivenObj = val(Leer.GetValue("Campaign" & i & " - Stage" & S, "NumGivenObj"))

1960                    If Not .NumGivenObj = 0 Then

1970                        ReDim .GivenObj(1 To .NumGivenObj) As Obj

1980                        For LoopB = 1 To .NumGivenObj
1990                            .GivenObj(LoopB).objIndex = val(Leer.GetValue("Campaign" & i & " - Stage" & S, "GivenObj" & LoopB & "Index"))
2000                            .GivenObj(LoopB).amount = val(Leer.GetValue("Campaign" & i & " - Stage" & S, "GivenObj" & LoopB & "Amount"))
2010                        Next LoopB

2020                    Else
2030                        ReDim .GivenObj(0)
2040                    End If

2050                End With

2060            Next S

2070        End With

2080    Next i

        '/////////////////////////////////////////READ//END////////////////////////////////////////////////

2090 Else
2100    Call WriteToConsole("Cargando campañas default...")
2110    Call LoadDefaultCampaigns

2120 End If

2130 Call WriteToConsole("Camapañas cargadas correctamente.")
2140 Set Leer = Nothing

2150 Exit Sub
ErrHandler:
2160 Call LogError("Error al cargar campañas. Se cargará la campaña por defecto " & err.Number & ": " & err.Description & " Linea: " & Erl)
2170 Call LoadDefaultCampaigns

End Sub

Public Sub LoadDefaultCampaigns()

10  On Error GoTo LoadDefaultCampaigns_Error

20  NumCampaigns = 2

30  ReDim Campaign(1 To NumCampaigns) As Campaign

40  With Campaign(1)

50      With .Properties
60          .Name = "Cacería de Lobos"
70          Campaign(1).Rewards.Description = "Debes matar 20 lobos y entregarme sus pieles"
80          .Dialog.FirstTalk = "Hola aventurero tengo una misión para ti!"
90          .Dialog.SecondTalk = "Esta daga puede servirte. Ahora ve en busca de esas criaturas!"
100         .Dialog.ThirdTalk = "¿Todavía no tienes las pieles?"
110         .Dialog.FourthTalk = "Ah! Veo que vienes en busca de tu recompensa"
120         .Dialog.FifthTalk = "Toma esta espada y este hechizo"
130         .NumStages = 2
140         .Redoable = 1
150         .Timing = 0
160         .FinishWhenDie = True
170     End With

180     With .Requirements
190         .MinLvl = 1
200         .MaxLvl = 45
210         .PreviousCampaign = 0
220         .Class = 0
230         .Race = 0
240         .Genre = 0
250         .Alignment = 0
260         .Faction = 0
270         .Rank = 0
280     End With

290     With .Rewards
300         .RewardExp = 1500
310         .RewardGold = 1500
320         .NumRewardObj = 2
330         ReDim .RewardObj(1 To .NumRewardObj) As Obj
340         .RewardObj(1).objIndex = 197
350         .RewardObj(1).amount = 1
360         .RewardObj(2).objIndex = 164
370         .RewardObj(2).amount = 1
380     End With

390     ReDim .Stages(1 To .Properties.NumStages) As CampaignStage

400     With .Stages(1)
410         With .Properties
420             .Description = "Matar 20 lobos"
430             .Dialog.FirstTalk = vbNullString
440             .Dialog.SecondTalk = vbNullString
450             .Dialog.ThirdTalk = vbNullString
460             .Dialog.FourthTalk = vbNullString
470             .Dialog.FifthTalk = vbNullString
480             .Timing = 0
490         End With

500         With .Objetives
510             .TargetNPC.Index = 501
520             .TargetNPC.amount = 20
530             .TargetNPC.Action = 1
540             .TargetObj.objIndex = 0
550             .TargetObj.amount = 0
560             .TargetUser.MinLvl = 0
570             .TargetUser.MaxLvl = 0
580             .TargetUser.amount = 0
590             .TargetUser.Alignment = 0
600             .TargetUser.Faction = 0
610             .TargetUser.Rank = 0
620             .TargetLocation.Trigger = 0
630             .TargetLocation.posX = 0
640             .TargetLocation.posY = 0
650             .TargetLocation.Map = 0
660             .KeyWord = ""
670         End With

680         .NumGivenObj = 1
690         ReDim .GivenObj(1 To .NumGivenObj) As Obj
700         .GivenObj(1).objIndex = 165
710         .GivenObj(1).amount = 1
720     End With

730     With .Stages(2)
740         With .Properties
750             .Description = "Entregar las pieles"
760             .Dialog.FirstTalk = vbNullString
770             .Dialog.SecondTalk = vbNullString
780             .Dialog.ThirdTalk = vbNullString
790             .Dialog.FourthTalk = vbNullString
800             .Dialog.FifthTalk = vbNullString
810             .Timing = 0
820         End With

830         With .Objetives
840             .TargetNPC.Index = 128
850             .TargetNPC.amount = 0
860             .TargetNPC.Action = 3
870             .TargetObj.objIndex = 414
880             .TargetObj.amount = 20
890             .TargetUser.MinLvl = 0
900             .TargetUser.MaxLvl = 0
910             .TargetUser.amount = 0
920             .TargetUser.Alignment = 0
930             .TargetUser.Faction = 0
940             .TargetUser.Rank = 0
950             .TargetLocation.Trigger = 0
960             .TargetLocation.posX = 0
970             .TargetLocation.posY = 0
980             .TargetLocation.Map = 0
990             .KeyWord = ""
1000        End With

1010        .NumGivenObj = 0
1020        ReDim .GivenObj(0)
1030    End With

1040 End With

1050 With Campaign(2)

1060    With .Properties
1070        .Name = "Tumulto en la ciudad"
1080        Campaign(2).Rewards.Description = "Le han robado al Gobernador y necesitamos que averigues quién fue"
1090        .Dialog.FirstTalk = "Tengo un trabajo para ofrecerte!"
1100        .Dialog.SecondTalk = "Ve a hablar con el sacerdote. Apresúrate!"
1110        .Dialog.ThirdTalk = "¿Todavía no tienes la información? Si la tienes ve a decirle al Gobernador!"
1120        .Dialog.FourthTalk = "Ah! Veo que vienes en busca de tu recompensa"
1130        .Dialog.FifthTalk = "Gracias por tu ayuda! Estos objetos te servirán para tu entrenamiento"
1140        .NumStages = 7
1150        .Redoable = 1
1160        .Timing = 0
1170        .FinishWhenDie = False
1180    End With

1190    With .Requirements
1200        .MinLvl = 1
1210        .MaxLvl = 45
1220        .PreviousCampaign = 0
1230        .Class = 0
1240        .Race = 0
1250        .Genre = 0
1260        .Alignment = 0
1270        .Faction = 0
1280        .Rank = 0
1290    End With

1300    With .Rewards
1310        .RewardExp = 15000
1320        .RewardGold = 1500000
1330        .NumRewardObj = 4
1340        ReDim .RewardObj(1 To .NumRewardObj) As Obj
1350        .RewardObj(1).objIndex = 238
1360        .RewardObj(1).amount = 1
1370        .RewardObj(2).objIndex = 366
1380        .RewardObj(2).amount = 1
1390        .RewardObj(3).objIndex = 38
1400        .RewardObj(3).amount = 10000
1410        .RewardObj(4).objIndex = 205
1420        .RewardObj(4).amount = 1
1430    End With

1440    ReDim .Stages(1 To .Properties.NumStages) As CampaignStage

1450    With .Stages(1)
1460        With .Properties
1470            .Description = "Hablar con el sacerdote"
1480            .Dialog.FirstTalk = "He oído los rumores pero no se quién es el ladrón. Quizás Cullighan sepa. El vende propiedades."
1490            .Dialog.SecondTalk = vbNullString
1500            .Dialog.ThirdTalk = vbNullString
1510            .Dialog.FourthTalk = vbNullString
1520            .Dialog.FifthTalk = vbNullString
1530            .Timing = 0
1540        End With

1550        With .Objetives
1560            .TargetNPC.Index = 5
1570            .TargetNPC.amount = 0
1580            .TargetNPC.Action = 2
1590            .TargetObj.objIndex = 0
1600            .TargetObj.amount = 0
1610            .TargetUser.MinLvl = 0
1620            .TargetUser.MaxLvl = 0
1630            .TargetUser.amount = 0
1640            .TargetUser.Alignment = 0
1650            .TargetUser.Faction = 0
1660            .TargetUser.Rank = 0
1670            .TargetLocation.Trigger = 0
1680            .TargetLocation.posX = 0
1690            .TargetLocation.posY = 0
1700            .TargetLocation.Map = 0
1710            .KeyWord = ""
1720        End With

1730        .NumGivenObj = 0
1740        ReDim .GivenObj(0)
1750    End With

1760    With .Stages(2)
1770        With .Properties
1780            .Description = "Hablar con Cullighan"
1790            .Dialog.FirstTalk = "Puede ser que yo sepa quién es el ladrón, pero deberás traerme 5 cervezas si quieres mi ayuda"
1800            .Dialog.SecondTalk = vbNullString
1810            .Dialog.ThirdTalk = vbNullString
1820            .Dialog.FourthTalk = vbNullString
1830            .Dialog.FifthTalk = vbNullString
1840            .Timing = 0
1850        End With

1860        With .Objetives
1870            .TargetNPC.Index = 34
1880            .TargetNPC.amount = 0
1890            .TargetNPC.Action = 2
1900            .TargetObj.objIndex = 0
1910            .TargetObj.amount = 0
1920            .TargetUser.MinLvl = 0
1930            .TargetUser.MaxLvl = 0
1940            .TargetUser.amount = 0
1950            .TargetUser.Alignment = 0
1960            .TargetUser.Faction = 0
1970            .TargetUser.Rank = 0
1980            .TargetLocation.Trigger = 0
1990            .TargetLocation.posX = 0
2000            .TargetLocation.posY = 0
2010            .TargetLocation.Map = 0
2020            .KeyWord = ""
2030        End With

2040        .NumGivenObj = 0
2050        ReDim .GivenObj(0)
2060    End With

2070    With .Stages(3)
2080        With .Properties
2090            .Description = "Conseguir 5 cervezas"
2100            .Dialog.FirstTalk = vbNullString
2110            .Dialog.SecondTalk = vbNullString
2120            .Dialog.ThirdTalk = vbNullString
2130            .Dialog.FourthTalk = vbNullString
2140            .Dialog.FifthTalk = vbNullString
2150            .Timing = 0
2160        End With

2170        With .Objetives
2180            .TargetNPC.Index = 0
2190            .TargetNPC.amount = 0
2200            .TargetNPC.Action = 0
2210            .TargetObj.objIndex = 160
2220            .TargetObj.amount = 5
2230            .TargetUser.MinLvl = 0
2240            .TargetUser.MaxLvl = 0
2250            .TargetUser.amount = 0
2260            .TargetUser.Alignment = 0
2270            .TargetUser.Faction = 0
2280            .TargetUser.Rank = 0
2290            .TargetLocation.Trigger = 0
2300            .TargetLocation.posX = 0
2310            .TargetLocation.posY = 0
2320            .TargetLocation.Map = 0
2330            .KeyWord = ""
2340        End With

2350        .NumGivenObj = 0
2360        ReDim .GivenObj(0)
2370    End With

2380    With .Stages(4)
2390        With .Properties
2400            .Description = "Llevarle las cervezas a Cullighan"
2410            .Dialog.FirstTalk = "Vamos hombre! Todavía estoy esperando!"
2420            .Dialog.SecondTalk = "Hip Hip... Lo he olvidado. Habla con Nelmasil, el pregonero, el seguro te va a ayudar Hip Hip!"
2430            .Dialog.ThirdTalk = "No intentes pasarte de listo! No tienes la cantidad que te pedí!"
2440            .Dialog.FourthTalk = vbNullString
2450            .Dialog.FifthTalk = vbNullString
2460            .Timing = 0
2470        End With

2480        With .Objetives
2490            .TargetNPC.Index = 34
2500            .TargetNPC.amount = 0
2510            .TargetNPC.Action = 3
2520            .TargetObj.objIndex = 160
2530            .TargetObj.amount = 5
2540            .TargetUser.MinLvl = 0
2550            .TargetUser.MaxLvl = 0
2560            .TargetUser.amount = 0
2570            .TargetUser.Alignment = 0
2580            .TargetUser.Faction = 0
2590            .TargetUser.Rank = 0
2600            .TargetLocation.Trigger = 0
2610            .TargetLocation.posX = 0
2620            .TargetLocation.posY = 0
2630            .TargetLocation.Map = 0
2640            .KeyWord = ""
2650        End With

2660        .NumGivenObj = 0
2670        ReDim .GivenObj(0)
2680    End With

2690    With .Stages(5)
2700        With .Properties
2710            .Description = "Hablar con Nelmasil"
2720            .Dialog.FirstTalk = "Me importa un comino lo que le pase al Gobernador!! Ve a buscar ayuda en otro lado. Los sastres siempre tienen información"
2730            .Dialog.SecondTalk = vbNullString
2740            .Dialog.ThirdTalk = vbNullString
2750            .Dialog.FourthTalk = vbNullString
2760            .Dialog.FifthTalk = vbNullString
2770            .Timing = 0
2780        End With

2790        With .Objetives
2800            .TargetNPC.Index = 128
2810            .TargetNPC.amount = 0
2820            .TargetNPC.Action = 2
2830            .TargetObj.objIndex = 0
2840            .TargetObj.amount = 0
2850            .TargetUser.MinLvl = 0
2860            .TargetUser.MaxLvl = 0
2870            .TargetUser.amount = 0
2880            .TargetUser.Alignment = 0
2890            .TargetUser.Faction = 0
2900            .TargetUser.Rank = 0
2910            .TargetLocation.Trigger = 0
2920            .TargetLocation.posX = 0
2930            .TargetLocation.posY = 0
2940            .TargetLocation.Map = 0
2950            .KeyWord = ""
2960        End With

2970        .NumGivenObj = 0
2980        ReDim .GivenObj(0)
2990    End With

3000    With .Stages(6)
3010        With .Properties
3020            .Description = "Hablar con uno de los sastres"
3030            .Dialog.FirstTalk = "Yo se quién ha sido el ladrón. Pero necesito mates 30 serpientes porque me vuelvan loca y no puedo trabajar!! Luego regresa a hablar conmigo"
3040            .Dialog.SecondTalk = vbNullString
3050            .Dialog.ThirdTalk = vbNullString
3060            .Dialog.FourthTalk = vbNullString
3070            .Dialog.FifthTalk = vbNullString
3080            .Timing = 0
3090        End With

3100        With .Objetives
3110            .TargetNPC.Index = 19
3120            .TargetNPC.amount = 0
3130            .TargetNPC.Action = 2
3140            .TargetObj.objIndex = 0
3150            .TargetObj.amount = 0
3160            .TargetUser.MinLvl = 0
3170            .TargetUser.MaxLvl = 0
3180            .TargetUser.amount = 0
3190            .TargetUser.Alignment = 0
3200            .TargetUser.Faction = 0
3210            .TargetUser.Rank = 0
3220            .TargetLocation.Trigger = 0
3230            .TargetLocation.posX = 0
3240            .TargetLocation.posY = 0
3250            .TargetLocation.Map = 0
3260            .KeyWord = ""
3270        End With

3280        .NumGivenObj = 0
3290        ReDim .GivenObj(0)
3300    End With

3310    With .Stages(7)
3320        With .Properties
3330            .Description = "Matar 3 serpientes"
3340            .Dialog.FirstTalk = vbNullString
3350            .Dialog.SecondTalk = vbNullString
3360            .Dialog.ThirdTalk = vbNullString
3370            .Dialog.FourthTalk = vbNullString
3380            .Dialog.FifthTalk = vbNullString
3390            .Timing = 0
3400        End With

3410        With .Objetives
3420            .TargetNPC.Index = 504
3430            .TargetNPC.amount = 3
3440            .TargetNPC.Action = 1
3450            .TargetObj.objIndex = 0
3460            .TargetObj.amount = 0
3470            .TargetUser.MinLvl = 0
3480            .TargetUser.MaxLvl = 0
3490            .TargetUser.amount = 0
3500            .TargetUser.Alignment = 0
3510            .TargetUser.Faction = 0
3520            .TargetUser.Rank = 0
3530            .TargetLocation.Trigger = 0
3540            .TargetLocation.posX = 0
3550            .TargetLocation.posY = 0
3560            .TargetLocation.Map = 0
3570            .KeyWord = ""
3580        End With

3590        .NumGivenObj = 0
3600        ReDim .GivenObj(0)
3610    End With

3620    With .Stages(8)
3630        With .Properties
3640            .Description = "Volver a hablar con la sastre"
3650            .Dialog.FirstTalk = "Muchas gracias por matar esas criaturas. Ahora te lo diré! El ladrón es... Nelmasil!!!"
3660            .Dialog.SecondTalk = vbNullString
3670            .Dialog.ThirdTalk = vbNullString
3680            .Dialog.FourthTalk = vbNullString
3690            .Dialog.FifthTalk = vbNullString
3700            .Timing = 0
3710        End With

3720        With .Objetives
3730            .TargetNPC.Index = 19
3740            .TargetNPC.amount = 0
3750            .TargetNPC.Action = 2
3760            .TargetObj.objIndex = 0
3770            .TargetObj.amount = 0
3780            .TargetUser.MinLvl = 0
3790            .TargetUser.MaxLvl = 0
3800            .TargetUser.amount = 0
3810            .TargetUser.Alignment = 0
3820            .TargetUser.Faction = 0
3830            .TargetUser.Rank = 0
3840            .TargetLocation.Trigger = 0
3850            .TargetLocation.posX = 0
3860            .TargetLocation.posY = 0
3870            .TargetLocation.Map = 0
3880            .KeyWord = ""
3890        End With

3900        .NumGivenObj = 0
3910        ReDim .GivenObj(0)
3920    End With

3930    With .Stages(9)
3940        With .Properties
3950            .Description = "Decirle al Gobernador quién es el ladrón"
3960            .Dialog.FirstTalk = vbNullString
3970            .Dialog.SecondTalk = vbNullString
3980            .Dialog.ThirdTalk = vbNullString
3990            .Dialog.FourthTalk = vbNullString
4000            .Dialog.FifthTalk = vbNullString
4010            .Timing = 0
4020        End With

4030        With .Objetives
4040            .TargetNPC.Index = 13
4050            .TargetNPC.amount = 0
4060            .TargetNPC.Action = 5
4070            .TargetObj.objIndex = 0
4080            .TargetObj.amount = 0
4090            .TargetUser.MinLvl = 0
4100            .TargetUser.MaxLvl = 0
4110            .TargetUser.amount = 0
4120            .TargetUser.Alignment = 0
4130            .TargetUser.Faction = 0
4140            .TargetUser.Rank = 0
4150            .TargetLocation.Trigger = 0
4160            .TargetLocation.posX = 0
4170            .TargetLocation.posY = 0
4180            .TargetLocation.Map = 0
4190            .KeyWord = "Nelmasil"
4200        End With

4210        .NumGivenObj = 0
4220        ReDim .GivenObj(0)
4230    End With
4240 End With

4250 On Error GoTo 0
4260 Exit Sub

LoadDefaultCampaigns_Error:

4270 Call LogError("Error " & err.Number & " Descripción: & (" & err.Description & ") del procedimiento LoadDefaultCampaigns del Módulo mod_Campaing" & " En la linea: " & Erl)

End Sub

Public Function CanDoThisCampaign(ByVal UserIndex As Integer, ByVal Number As Integer, ByRef sErrorMsg As String) As Boolean

'Función para saber si el usuario puede realizar la Campaña Number

Dim Alignment                   As Byte    '1)Ciudadano 2)Criminal
Dim Faction                     As Byte    '1)Armada 2)Caos

10  On Error GoTo CanDoThisCampaign_Error

20  Dim Rank                    As Byte    'Armada: 1)Aprendiz 2)Escudero 3)Soldado 4)Sargento 5)Teniente 6)Comandante 7)Capitán 8)Senescal 9)Mariscal 10)Condestable 11)Ejecutor Imperial 12)Protector del Reino 13)Avatar de la Justicia 14)Guardián del Bien 15)Campeón de la Luz
    'Caos: 1)Acólito 2)Alama Corrupta 3)Paria 4)Condenado 5)Esbirro 6)Sanguinario 7)Corruptor 8)Heraldo Impío 9)Caballero de la Oscuridad 10)Señor del Miedo 11)Ejecutor Infernal 12)Protector del Averno 13)Avatar de la Destrucción 14)Guardián del Mal 15)Campeón de la Oscuridad

30  With UserList(UserIndex)

40      If Criminal(UserIndex) Then
50          Alignment = 2
60      Else
70          Alignment = 1
80      End If

90      If esArmada(UserIndex) Then
100         Faction = 1
110     ElseIf esCaos(UserIndex) Then
120         Faction = 2
130     Else
140         Faction = 0
150     End If

160     If Faction = 1 Then
170         Rank = (.Faccion.RangeRoyal)
180     ElseIf Faction = 2 Then
190         Rank = (.Faccion.RangeCaos)
200     Else
210         Rank = 0
220     End If

230     If Number > NumCampaigns Then
240         Call LogError("El usuario: " & .Name & " intenta realizar una misión que supera el numero máximo de misiones, numero: " & Number & " Cantidad máxima de misiones: " & NumCampaigns)
250         sErrorMsg = "Estás intentando realizar una misión inválida. Avisa a un administrador."
260         Exit Function
270     End If

280     If Number > 0 Then
290         If .Stats.ELV < Campaign(Number).Requirements.MinLvl Then
300             sErrorMsg = "{1004}" & IIf(Campaign(Number).Requirements.MinLvl > 0, " como mínimo " & Campaign(Number).Requirements.MinLvl, "") & IIf(Campaign(Number).Requirements.MaxLvl > 0, " como máximo " & Campaign(Number).Requirements.MaxLvl, "") & " para realizar la misión " & Campaign(Number).Properties.Name
310             Exit Function
320         End If

330         If Campaign(Number).Requirements.MaxLvl <> 0 And .Stats.ELV > Campaign(Number).Requirements.MaxLvl Then
340             sErrorMsg = "{1004}" & IIf(Campaign(Number).Requirements.MinLvl > 0, " como mínimo " & Campaign(Number).Requirements.MinLvl, "") & IIf(Campaign(Number).Requirements.MaxLvl > 0, " como máximo " & Campaign(Number).Requirements.MaxLvl, "") & " para realizar la misión " & Campaign(Number).Properties.Name
350             Exit Function
360         End If

370         If Campaign(Number).Requirements.Class <> 0 And .Clase <> Campaign(Number).Requirements.Class Then
380             sErrorMsg = "{1005}"    'La misión no es para tu clase.
390             Exit Function
400         End If

410         If Campaign(Number).Requirements.Race <> 0 And .raza <> Campaign(Number).Requirements.Race Then
420             sErrorMsg = "{1006}"    'La misión no es para tu raza.
430             Exit Function
440         End If

450         If Campaign(Number).Requirements.Genre <> 0 And .Genero <> Campaign(Number).Requirements.Genre Then
460             sErrorMsg = "{1007}"    'La misión no es para tu genero o sexo.
470             Exit Function
480         End If

490         If Campaign(Number).Requirements.PreviousCampaign <> 0 Then
500             If Not HasDoneThisCampaign(UserIndex, Campaign(Number).Requirements.PreviousCampaign) Then
510                 sErrorMsg = "{1008}" & Campaign(Number).Requirements.PreviousCampaign & " llamada: " & Campaign(Campaign(Number).Requirements.PreviousCampaign).Properties.Name    'Para realizar esta misión, necesitas tener realizada previamente la misión número
520                 Exit Function
530             End If
540         End If

550         If Campaign(Number).Requirements.Alignment <> 0 And Alignment <> Campaign(Number).Requirements.Alignment Then
560             sErrorMsg = "{1009}"    'La misión no es para tu alineación o status.
570             Exit Function
580         End If

590         If Campaign(Number).Requirements.Faction <> 0 And Faction <> Campaign(Number).Requirements.Faction Then
600             sErrorMsg = "{1010}"    'La misión no es para tu facción.
610             Exit Function
620         End If

630         If Campaign(Number).Requirements.Rank <> 0 And Rank < Campaign(Number).Requirements.Rank Then
640             If .Faccion.RoyalArmy > 0 Then
650                 sErrorMsg = "{1011} Necesitas ser: " & IIf(.Genero = eGenero.Hombre, TitulosReal(Campaign(Number).Requirements.Rank).NombreBoy, TitulosReal(Campaign(Number).Requirements.Rank).NombreGirl)    'La misión no es para tu rango de facción.
660             ElseIf .Faccion.CaosArmy > 0 Then
670                 sErrorMsg = "{1011} Necesitas ser: " & IIf(.Genero = eGenero.Hombre, TitulosCaos(Campaign(Number).Requirements.Rank).NombreBoy, TitulosCaos(Campaign(Number).Requirements.Rank).NombreGirl)    'La misión no es para tu rango de facción.
680             End If
690             Exit Function
700         End If

710         If Not Campaign(Number).Properties.Redoable Then
720             If HasDoneThisCampaign(UserIndex, Number) Then
730                 sErrorMsg = Campaign(Number).Properties.Name & " {1012}"    ' no se puede repetir.
740                 Exit Function
750             End If
760         End If

770         If Campaign(Number).Rewards.Forgive > 0 Then
780             If Not .Guild Is Nothing Then
790                 If .Guild.getAlignment = eGUILD_ALIGNMENT.ALINEACION_CRIMINAL Or .Guild.getAlignment = eGUILD_ALIGNMENT.ALINEACION_LEGION Then
800                     sErrorMsg = "No puedes realizar ésta misión siendo de un clan de alineación Criminal, o Legión. Debes salir del clan."
810                     Exit Function
820                 End If
830             End If
840         End If

850         If Campaign(Number).Rewards.EnlistFaction > 0 And Faction > 0 Then
860             sErrorMsg = "No puedes realizar ésta misión debido a tu facción."
870             Exit Function
880         End If

890     End If

900     CanDoThisCampaign = True

910 End With

920 On Error GoTo 0
930 Exit Function

CanDoThisCampaign_Error:

940 Call LogError("Error " & err.Number & " (" & err.Description & ") en el procedimiento CanDoThisCampaign del módulo Módulo modCampaign en la línea: " & Erl() & " NICK: " & UserList(UserIndex).Name)

End Function

Public Function HasDoneThisCampaign(ByVal UserIndex As Integer, ByVal Number As Integer) As Boolean

'Función para saber si el usuario ya realizó la Campaña Number

Dim Current                     As Integer
Dim i                           As Long
Dim CantCampaignsDone           As Long

10  On Error GoTo HasDoneThisCampaign_Error

20  With UserList(UserIndex).Campaign

30      If Len(.CampaignsHasDone) <= 0 Then
40          HasDoneThisCampaign = False
50          Exit Function
60      End If

70      CantCampaignsDone = FieldCount(.CampaignsHasDone, 45)
80      For i = 1 To CantCampaignsDone
90          Current = val(ReadField(i, .CampaignsHasDone, 45))
100         If Current = Number Then
110             If Not Campaign(Number).Properties.Redoable Then
120                 HasDoneThisCampaign = True
130                 Exit For
140             Else
150                 HasDoneThisCampaign = False
160             End If
170         Else
180             HasDoneThisCampaign = False
190         End If
200     Next i

210 End With

220 On Error GoTo 0
230 Exit Function

HasDoneThisCampaign_Error:

240 Call LogError("Error " & err.Number & " (" & err.Description & ") procedimiento HasDoneThisCampaign Módulo modCampaign línea: " & Erl())

End Function

Public Sub AddCampaignsHasDone(ByVal UserIndex As Integer, ByVal Number As Integer)

    On Error GoTo AddCampaignsHasDone_Error

10  With UserList(UserIndex).Campaign

20      If Not HasDoneThisCampaign(UserIndex, Number) Then    'Parcheo por las redoables

30          If StrComp(.CampaignsHasDone, vbNullString) = 0 Then
40              .CampaignsHasDone = Number
50          Else
60              .CampaignsHasDone = .CampaignsHasDone & "-" & Number
70          End If

80      End If

90  End With

    On Error GoTo 0
    Exit Sub

AddCampaignsHasDone_Error:

    Call LogError("Error " & err.Number & " (" & err.Description & ") procedimiento AddCampaignsHasDone Módulo modCampaign línea: " & Erl())

End Sub

Public Sub RightClickEvents(ByVal UserIndex As Integer, ByVal Map As Byte, ByVal x As Integer, ByVal Y As Integer)

'Eventos asociados a la acción click derecho

Dim NpcIndex                    As Integer

10  On Error GoTo RightClickEvents_Error

20  With UserList(UserIndex)

30      If (Abs(.pos.Y - Y) > RANGO_VISION_Y) Or (Abs(.pos.x - x) > RANGO_VISION_X) Then
40          Exit Sub
50      End If

60      If MapData(Map, x, Y).NpcIndex > 0 Then
70          NpcIndex = MapData(Map, x, Y).NpcIndex
80          Call SendData(SendTarget.ToPCArea, UserIndex, PrepareMessageRemoveCharDialog(NpcIndex))
90          If Distancia(NpcList(NpcIndex).pos, .pos) > 8 Then
100             Call WriteConsoleMsg(UserIndex, "{01}", FontTypeNames.FONTTYPE_INFO)
110             Exit Sub
120         End If
130         Call GiveChatOverHead(UserIndex, NpcIndex)
140     End If

150 End With

160 On Error GoTo 0
170 Exit Sub

RightClickEvents_Error:

180 Call LogError("Error " & err.Number & " Descripción: & (" & err.Description & ") del procedimiento RightClickEvents del Módulo mod_Campaing" & " En la linea: " & Erl)

End Sub

Public Sub GiveChatOverHead(ByVal UserIndex As Integer, ByVal NpcIndex As Integer)

'Encuentra un chat para mostrar sobre el Npc

Dim Text                        As String

10  On Error GoTo GiveChatOverHead_Error

20  With UserList(UserIndex).Campaign

30      If .Current > 0 Then

            Dim i               As Integer

40          If Not .WaitingReward Then
50              For i = 1 To Campaign(.Current).Properties.NumStages

60                  If Campaign(.Current).Stages(i).Objetives.TargetNPC.Index = NpcList(NpcIndex).ID Then

70                      If Not .Stages(i).Done Then
80                          If Campaign(.Current).Stages(i).Properties.StageRequired > 0 Then
90                              If .Stages(Campaign(.Current).Stages(i).Properties.StageRequired).Done Then
100                                 Text = Campaign(.Current).Stages(i).Properties.Dialog.FirstTalk
110                             Else
120                                 Text = Campaign(.Current).Stages(i).Properties.Description
130                             End If
140                         Else
150                             Text = Campaign(.Current).Stages(i).Properties.Dialog.SecondTalk
160                         End If
170                         Exit For
180                     Else
190                         If .WaitingReward Then    '@ Está esperando recompensa?
200                             Text = Campaign(.Current).Stages(i).Properties.Dialog.FourthTalk
210                         Else
220                             Text = Campaign(.Current).Stages(i).Properties.Dialog.ThirdTalk
230                         End If
240                     End If
250                 End If
260             Next i
270         Else
280             If UserList(UserIndex).flags.TargetNPC > 0 Then
290                 If .NpcIndexGiver = NpcList(UserList(UserIndex).flags.TargetNPC).ID Then    'If UserList(UserIndex).flags.TargetNPC > 0 Then
300                     If UserList(UserIndex).Campaign.WaitingReward Then
310                         Call FinishCompletedCampaign(UserIndex, UserList(UserIndex).flags.TargetNPC)
320                     End If
330                 Else
340                     Call WriteConsoleMsg(UserIndex, "Para terminar la misión, debes hacer clic en la criatura que te dió inicialmente la misma.", FontTypeNames.FONTTYPE_CAMPAIGN)
350                 End If
360             End If
370         End If

390     ElseIf Len(NpcList(NpcIndex).CampaignsGiven) > 0 Then
400         Text = CampaignNpcChat(UserIndex, NpcIndex, .Current)
410     End If

420 End With

430 If Len(Text) > 0 Then
440     Call ShowCampaignChat(UserIndex, NpcIndex, Text)
450 End If

460 On Error GoTo 0
470 Exit Sub

GiveChatOverHead_Error:

480 Call LogError("Error " & err.Number & " Descripción: & (" & err.Description & ") del procedimiento GiveChatOverHead del Módulo mod_Campaing" & " En la linea: " & Erl)

End Sub

Public Function CampaignNpcChat(ByVal UserIndex As Integer, ByVal NpcIndex As Integer, ByVal CampaignNumber As Integer) As String

Dim Number                      As Integer
Dim iCantQuest                  As Integer
Dim i                           As Long
Dim sErrorMsg                   As String
Dim sFinalMsg                   As String

    On Error GoTo CampaignNpcChat_Error

10  With UserList(UserIndex).Campaign

20      If CampaignNumber = 0 Then

30          iCantQuest = FieldCount(NpcList(NpcIndex).CampaignsGiven, 45)

40          For i = 1 To iCantQuest
50              Number = val(ReadField(i, NpcList(NpcIndex).CampaignsGiven, 45))

60              If Not CanDoThisCampaign(UserIndex, Number, sErrorMsg) Then
70                  sFinalMsg = sFinalMsg & vbCrLf & sErrorMsg
80                  Number = -1
90                  .CanViewCampaignList = False
                    ' Call WriteConsoleMsg(UserIndex, sErrorMsg, FontTypeNames.FONTTYPE_CAMPAIGN)
100             Else
110                 If HasDoneThisCampaign(UserIndex, Number) Then
120                     If i = iCantQuest Then
130                         CampaignNpcChat = "Hola aventurero. Ya no dispongo de nuevas misiones para ti. Si deseas repetir alguna escribe /LISTAQUEST"
140                         .OffererNpcIndex = NpcIndex
150                         .CanViewCampaignList = True
160                         Exit Function
170                     End If

                        'Exit For
180                 Else
190                     .CanViewCampaignList = True
200                     Exit For
210                 End If
220             End If
230         Next i

240         If Number <= 0 Then
                'CampaignNpcChat = NpcList(NpcIndex).desc
250             .CanDoThisOne = 0
260             .OffererNpcIndex = 0
270         Else
280             CampaignNpcChat = Campaign(Number).Properties.Dialog.FirstTalk
290             .CanDoThisOne = Number
300             .OffererNpcIndex = NpcIndex
310         End If

320         If Len(sFinalMsg) > 0 Then
330             Call WriteConsoleMsg(UserIndex, sFinalMsg, FontTypeNames.FONTTYPE_CAMPAIGN)
340         End If

350         Exit Function
360     End If

370     If .NpcIndexGiver = NpcList(NpcIndex).ID Then
380         If .Current > 0 Then
390             If Not .WaitingReward Then
400                 CampaignNpcChat = Campaign(CampaignNumber).Properties.Dialog.ThirdTalk
410             Else
420                 CampaignNpcChat = Campaign(CampaignNumber).Properties.Dialog.FourthTalk
                    'Call FinishCompletedCampaign(UserIndex, UserList(UserIndex).flags.TargetNPC)
430             End If
440         End If
450     End If

460 End With

    On Error GoTo 0
    Exit Function

CampaignNpcChat_Error:

    Call LogError("Error " & err.Number & " (" & err.Description & ") procedimiento CampaignNpcChat Módulo modCampaign línea: " & Erl())

End Function

Public Function CampaignDblClickEvents(ByVal UserIndex As Integer, ByVal NpcIndex As Integer) As Boolean

Dim i                           As Integer
Dim HaveCampaign                As String

10  On Error GoTo CampaignDblClickEvents_Error

20  With UserList(UserIndex)

30      If .flags.Muerto <> 0 Then
40          Call WriteConsoleMsg(UserIndex, "{1330}", FontTypeNames.FONTTYPE_INFO)    '¡Estás muerto!
50          CampaignDblClickEvents = False
60          Exit Function
70      End If

80      If Distancia(.pos, NpcList(NpcIndex).pos) > 8 Then
90          Call WriteConsoleMsg(UserIndex, "{04}", FontTypeNames.FONTTYPE_INFO)    'Estás demasiado lejos.
100         CampaignDblClickEvents = False
110         Exit Function
120     End If

130     With .Campaign
140         If .CanDoThisOne > 0 Then
150             If .CanViewCampaignList And .OffererNpcIndex = NpcIndex Then
160                 Call WriteGiveCampaignList(UserIndex, .OffererNpcIndex)
170                 CampaignDblClickEvents = True
180                 Exit Function
190             ElseIf .Current > 0 Then
200                 For i = 1 To Campaign(.Current).Properties.NumStages
210                     If Not .Stages(i).Done Then
220                         If Campaign(.Current).Stages(i).Objetives.TargetNPC.Index = NpcList(NpcIndex).ID Then
230                             Call CampaignNpcDblClickEvents(UserIndex, NpcIndex)
240                             CampaignDblClickEvents = True
250                             Exit Function
260                         End If
270                     End If
280                 Next i
290             Else
300                 HaveCampaign = WhichOnes(UserIndex, NpcIndex)
                    'Si quieres conseguir una misión, ve con los personajes que tienen un signo de pregunta sobre su cabeza y haz DOBLE CLIC 'DERECHO' sobre él.
310                 If Len(HaveCampaign) > 0 Then
320                     Call WriteConsoleMsg(UserIndex, "{1014}", FontTypeNames.FONTTYPE_CAMPAIGN)    'Si quieres conseguir una misión, ve con los personajes que tienen un signo de pregunta sobre su cabeza y haz DOBLE CLIC 'DERECHO' sobre él.
330                     CampaignDblClickEvents = False
340                 Else
350                     CampaignDblClickEvents = True
360                 End If
370             End If
380         ElseIf .Current > 0 Then
390             CampaignDblClickEvents = CampaignNpcDblClickEvents(UserIndex, NpcIndex)
400         End If
410     End With
420 End With

430 'CampaignDblClickEvents = False

440 On Error GoTo 0
450 Exit Function

CampaignDblClickEvents_Error:

460 Call LogError("Error " & err.Number & " Descripción: & (" & err.Description & ") del procedimiento CampaignDblClickEvents del Módulo mod_Campaing" & " En la linea: " & Erl)

End Function

Public Function CampaignNpcDblClickEvents(ByVal UserIndex As Integer, ByVal NpcIndex As Integer) As Boolean

Dim i                           As Integer

10  On Error GoTo CampaignNpcDblClickEvents_Error

20  With UserList(UserIndex).Campaign
30      For i = 1 To Campaign(.Current).Properties.NumStages    '@ Recorro las posibilidades con un for.
40          If Not .Stages(i).Done Then
50              If Campaign(.Current).Stages(i).Objetives.TargetNPC.Index = NpcList(NpcIndex).ID Then

60                  Select Case Campaign(.Current).Stages(i).Objetives.TargetNPC.Action

                        Case eCampaingActions.Hablar

70                          If AccomplishObjetive(UserIndex, i) Then
80                              CampaignNpcDblClickEvents = True
90                          Else
100                             CampaignNpcDblClickEvents = False
110                             Exit For
120                         End If

130                         Exit For

140                     Case eCampaingActions.EntregarObj    'Entregar Obj

150                         If Not .Stages(i).ObjDelivered Then
160                             CampaignNpcDblClickEvents = DeliverCampaignObj(UserIndex)
170                         End If

180                         Exit For

190                     Case eCampaingActions.Encontrar    'Encontrar

200                         If AccomplishObjetive(UserIndex, i) Then
                                'Listo
210                             CampaignNpcDblClickEvents = True
220                         Else
230                             CampaignNpcDblClickEvents = False
240                         End If

250                         Exit For

260                     Case eCampaingActions.KeyWord    'Decir Keyword
270                         If Campaign(.Current).Stages(i).Properties.StageRequired > 0 Then
280                             If Not .Stages(Campaign(.Current).Stages(i).Properties.StageRequired).Done Then
290                                 Call WriteConsoleMsg(UserIndex, "Para realizar el objetivo '" & Campaign(.Current).Stages(i).Properties.Description & "' primero debes '" & Campaign(.Current).Stages(Campaign(.Current).Stages(i).Properties.StageRequired).Properties.Description & "'", FontTypeNames.FONTTYPE_CAMPAIGN)
300                                 CampaignNpcDblClickEvents = False
310                             Else
320                                 Call WriteRequestKeyword(UserIndex)
330                                 CampaignNpcDblClickEvents = True
340                             End If
350                         End If

360                         Exit For
370                 End Select
380             End If
390         End If
400     Next i
410 End With

420 On Error GoTo 0
430 Exit Function

CampaignNpcDblClickEvents_Error:

440 Call LogError("Error " & err.Number & " (" & err.Description & ") procedimiento CampaignNpcDblClickEvents Módulo modCampaign línea: " & Erl())

End Function

Public Function DeliverObjects(ByVal UserIndex As Integer, ByVal NpcIndex As Integer, ByVal tCurrentStage As Integer)

Dim objIndex                    As Integer
Dim ObjAmount                   As Integer
Dim Text                        As String

10  On Error GoTo DeliverObjects_Error

20  With UserList(UserIndex).Campaign

30      ObjAmount = Campaign(.Current).Stages(tCurrentStage).Objetives.TargetObj.amount
40      objIndex = Campaign(.Current).Stages(tCurrentStage).Objetives.TargetObj.objIndex

50      If TieneObjetos(objIndex, ObjAmount, UserIndex) Then
60          Text = Campaign(.Current).Stages(tCurrentStage).Properties.Dialog.SecondTalk
70          Call ShowCampaignChat(UserIndex, NpcIndex, Text)
80          Call QuitarObjetos(objIndex, ObjAmount, UserIndex)
90          Call AccomplishObjetive(UserIndex, tCurrentStage)
100         Call WriteConsoleMsg(UserIndex, "¡Excelente! Has entregado los ítems del objetivo " & Campaign(.Current).Stages(tCurrentStage).Properties.Description & " de la misión.", FontTypeNames.FONTTYPE_CAMPAIGN)
110         .Stages(tCurrentStage).ObjDelivered = True

            '@ Si completó todos los objetivos, entonces podemos solicitar recompensa.
120         If .StagesCompleted = Campaign(.Current).Properties.NumStages Then
130             .WaitingReward = True
140         End If
150     Else
160         If Campaign(.Current).Stages(tCurrentStage).Objetives.TargetObj.objIndex > 0 Then
170             Call WriteConsoleMsg(UserIndex, "Te faltan " & ObjData(Campaign(.Current).Stages(tCurrentStage).Objetives.TargetObj.objIndex).Name & " " & Campaign(.Current).Stages(tCurrentStage).Properties.Description & " de la misión.", FontTypeNames.FONTTYPE_CAMPAIGN)
180         End If
190         .Stages(tCurrentStage).Done = False
200         Text = Campaign(.Current).Stages(tCurrentStage).Properties.Dialog.ThirdTalk
210         Call ShowCampaignChat(UserIndex, NpcIndex, Text)
220     End If

230 End With

240 On Error GoTo 0
250 Exit Function

DeliverObjects_Error:

260 Call LogError("Error " & err.Number & " (" & err.Description & ") procedimiento DeliverObjects Módulo modCampaign línea: " & Erl())

End Function

Public Sub CampaignBegin(ByVal UserIndex As Integer)

Dim i                           As Integer
Dim iTargetNpc                  As Integer
Dim Text                        As String

10  On Error GoTo CampaignBegin_Error

20  iTargetNpc = UserList(UserIndex).flags.TargetNPC

30  With UserList(UserIndex).Campaign

40      .Current = .CanDoThisOne
        '.CurrentStage = 1
50      .WaitingReward = False

60      If .Current > 0 Then

70          ReDim .Stages(1 To (Campaign(.Current).Properties.NumStages)) As UserStagesCampaign

80          If .OffererNpcIndex <> 0 Then
90              .NpcIndexGiver = NpcList(.OffererNpcIndex).ID
100         Else
110             Call FinishUncompletedCampaign(UserIndex, CampaignFailReason.Leave)
120             Exit Sub
130         End If             'Falto esto

140         .Timing = 0
150         .CanDoThisOne = 0
160         .OffererNpcIndex = 0
170         .CanViewCampaignList = False

180         For i = 1 To Campaign(.Current).Properties.NumStages
                '                If i = 1 Then
                '                    Call GiveStageObj(UserIndex, i)
                '                End If
190             .Stages(i).Done = False
200             .Stages(i).StageTiming = 0    'Campaign(.Current).Stages(i).Properties.Timing
           
210             .Stages(i).AmountTarget = 0 'NUEVO!
                '.Stages(i).AmountTargetNpc = 0
                '.Stages(i).AmountTargetUser = 0
                '.Stages(i).AmountTargetObj = 0
               
             .Stages(i).HaveToFoundPlace = (val(Campaign(.Current).Stages(i).Objetives.TargetLocation.Trigger) <> 0 Or (val(Campaign(.Current).Stages(i).Objetives.TargetLocation.posX) <> 0 And val(Campaign(.Current).Stages(i).Objetives.TargetLocation.posY) <> 0 And val(Campaign(.Current).Stages(i).Objetives.TargetLocation.Map)) <> 0)
                '.Stages(i).HaveToFoundPlace = 0 'Testeamos algo '@ Esto estaba MUY MAL.

                '                If Campaign(.Current).Stages(i).Objetives.TargetNPC.Action = 0 And Campaign(.Current).Stages(i).Objetives.TargetObj.objIndex > 0 Then
                '                    If TieneObjetos(Campaign(.Current).Stages(i).Objetives.TargetObj.objIndex, Campaign(.Current).Stages(i).Objetives.TargetObj.amount, UserIndex) Then
                '                        Call AccomplishObjetive(UserIndex, i)
                '                    End If
                '                End If
250         Next i

260         Text = Campaign(.Current).Properties.Dialog.SecondTalk

270         Call WriteConsoleMsg(UserIndex, "{997}", FontTypeNames.FONTTYPE_CAMPAIGN)    'Has aceptado la misión
280         Call WriteConsoleMsg(UserIndex, "{998}", FontTypeNames.FONTTYPE_CAMPAIGN)    'Escribe /INFOQUEST para ver los detalles de la misma.
290         Call WriteToggleCampaignState(UserIndex)

300         If UserList(UserIndex).flags.TargetNPC > 0 Then
310             Call ShowCampaignChat(UserIndex, UserList(UserIndex).flags.TargetNPC, Text)
320         Else
330             Call FinishUncompletedCampaign(UserIndex, CampaignFailReason.Leave)    ' Call ShowCampaignChat(UserIndex, .NpcIndexGiver, Text)
340         End If
350     Else
360         Call WriteConsoleMsg(UserIndex, "Misión cancelada.", FontTypeNames.FONTTYPE_CAMPAIGN)
370     End If
380 End With

390 On Error GoTo 0
400 Exit Sub

CampaignBegin_Error:

410 Call LogError("Error " & err.Number & " (" & err.Description & ") procedimiento CampaignBegin Módulo modCampaign línea: " & Erl())

End Sub

Public Sub CampaignTime(ByVal UserIndex As Integer)

    On Error GoTo CampaignTime_Error

20  With UserList(UserIndex).Campaign

30      If .Current > 0 And UserList(UserIndex).flags.UserLogged And UserList(UserIndex).ConnIDValida And Len(UserList(UserIndex).Name) > 0 Then
40          If Campaign(.Current).Properties.Timing > 0 Then
                '@ Tiempo de la misión en general.
50              If Not .WaitingReward Then
60                  .Timing = .Timing + 1
70                  If .Timing >= Campaign(.Current).Properties.Timing Then
80                      Call FinishUncompletedCampaign(UserIndex, CampaignFailReason.Timing)
90                  End If
100             End If
110         End If

            Dim i               As Integer
120         For i = 1 To Campaign(.Current).Properties.NumStages
                '@ Tiempo del objetivo actual.

                '@ Acá en teoría, debería consultar si la única misión que queda por hacer, tiene tiempo Pero eso también hay que datearlo de esa forma, sino el tiempo de la misión nunca va a funcionar si una misión tiene 3 objetivos totales, y 2 de ellas tienen tiempo.
130             If val(Campaign(.Current).Stages(i).Properties.Timing) > 0 Then
140                 If Not .Stages(i).Done Then
150                     .Stages(i).StageTiming = .Stages(i).StageTiming + 1
160                     If val(.Stages(i).StageTiming) >= val(Campaign(.Current).Stages(i).Properties.Timing) Then
170                         Call ReloadStageTimed(UserIndex)
180                     End If

190                     If val(Campaign(.Current).Stages(i).Properties.Timing) > 60 Then
200                         If .Stages(i).StageTiming Mod 60 = 0 Then
210                             Call WriteConsoleMsg(UserIndex, "Tienes " & Round((val(Campaign(.Current).Stages(i).Properties.Timing) - .Stages(i).StageTiming) / 60, 0) & " minutos restantes para completar el objetivo.", FontTypeNames.FONTTYPE_CAMPAIGN)
220                         End If
230                     End If
240                     Exit For    '@ Cerramos el bucle.
250                 End If
260             End If
270         Next i
280     End If

290 End With

    On Error GoTo 0
    Exit Sub

CampaignTime_Error:

    Call LogError("Error " & err.Number & " (" & err.Description & ") procedimiento CampaignTime Módulo modCampaign línea: " & Erl())

End Sub

Public Sub FinishUncompletedCampaign(ByVal UserIndex As Integer, ByVal Reason As Byte)

    On Error GoTo FinishUncompletedCampaign_Error

10  Call ResetCampaignTempData(UserIndex)
20  Call WriteCloseCampaignForms(UserIndex)

30  Select Case Reason
        Case CampaignFailReason.Leave
40          Call WriteConsoleMsg(UserIndex, "{1003}", FontTypeNames.FONTTYPE_CAMPAIGN)    '¡Has abandonado la misión!

50      Case CampaignFailReason.Reject
60          Call WriteConsoleMsg(UserIndex, "{1002}", FontTypeNames.FONTTYPE_ADMIN)    '¡Has rechazado la misión!

70      Case CampaignFailReason.Death
80          Call WriteConsoleMsg(UserIndex, "{1001}", FontTypeNames.FONTTYPE_CAMPAIGN)    '¡Has muerto en una misión!
90          Call WriteConsoleMsg(UserIndex, "{1000}", FontTypeNames.FONTTYPE_CAMPAIGN)    '¡No has podido terminar la misión!

100     Case CampaignFailReason.Timing
110         Call WriteConsoleMsg(UserIndex, "{999}", FontTypeNames.FONTTYPE_CAMPAIGN)    '¡Se ha agotado el tiempo para cumplir el objetivo!
120         Call WriteConsoleMsg(UserIndex, "{1000}", FontTypeNames.FONTTYPE_CAMPAIGN)    '¡No has podido terminar la misión!

130 End Select

140 Call WriteToggleCampaignState(UserIndex)

    On Error GoTo 0
    Exit Sub

FinishUncompletedCampaign_Error:

    Call LogError("Error " & err.Number & " (" & err.Description & ") procedimiento FinishUncompletedCampaign Módulo modCampaign línea: " & Erl())

End Sub

Public Sub ResetCampaignTempData(ByVal UserIndex As Integer)

Dim i                           As Integer

    On Error GoTo ResetCampaignTempData_Error

10  With UserList(UserIndex).Campaign

20      If .Current > 0 Then

            '.CurrentStage = 0
30          .StagesCompleted = 0
40          .WaitingReward = False
50          .NpcIndexGiver = 0
60          .Timing = 0
70          .CanDoThisOne = 0
80          .OffererNpcIndex = 0
90          .CanViewCampaignList = False

100         For i = 1 To Campaign(.Current).Properties.NumStages
110             .Stages(i).StageTiming = 0
120             .Stages(i).AmountTarget = 0 'NUEVO!
'120             .Stages(i).AmountTargetNpc = 0
'130             .Stages(i).AmountTargetUser = 0
'140             .Stages(i).AmountTargetObj = 0
150             .Stages(i).HaveToFoundPlace = False
160             .Stages(i).Done = False
170             .Stages(i).ObjDelivered = False
180         Next i

190         .Current = 0
200     End If
210 End With

    On Error GoTo 0
    Exit Sub

ResetCampaignTempData_Error:

    Call LogError("Error " & err.Number & " (" & err.Description & ") procedimiento ResetCampaignTempData Módulo modCampaign línea: " & Erl())

End Sub

Public Sub ResetCampaignAllData(ByVal UserIndex As Integer)

Dim i                           As Integer

    On Error GoTo ResetCampaignAllData_Error

10  With UserList(UserIndex).Campaign

        '.CurrentStage = 0
20      .StagesCompleted = 0
30      .WaitingReward = False
40      .NpcIndexGiver = 0
50      .Timing = 0

60      If .Current > 0 Then
70          For i = 1 To Campaign(.Current).Properties.NumStages
80              .Stages(i).StageTiming = 0
90              .Stages(i).AmountTarget = 0 'NUEVO!
'90              .Stages(i).AmountTargetNpc = 0
'100             .Stages(i).AmountTargetUser = 0
'110             .Stages(i).AmountTargetObj = 0
120             .Stages(i).HaveToFoundPlace = False
130             .Stages(i).Done = False
140             .Stages(i).ObjDelivered = False
150         Next i
160     End If

170     .CanDoThisOne = 0
180     .OffererNpcIndex = 0
190     .CanViewCampaignList = False
200     .CampaignsHasDone = vbNullString
210     .Current = 0
220 End With

    On Error GoTo 0
    Exit Sub

ResetCampaignAllData_Error:

    Call LogError("Error " & err.Number & " (" & err.Description & ") procedimiento ResetCampaignAllData Módulo modCampaign línea: " & Erl())

End Sub

Function AddPointer(ByRef LastPointer As Integer) As Integer
    LastPointer = LastPointer + 1
    AddPointer = LastPointer
End Function

Public Sub LoadUserCampaignData(ByVal UserIndex As Integer, Data As String)

Dim LastPoint                   As Integer

    On Error GoTo LoadUserCampaignData_Error

10  If Not StrComp(Data, vbNullString) = 0 Then    'About
20      With UserList(UserIndex).Campaign
            'Ejemplo: 19-0-218-0-19-0-0-0-0-0-14-0-0-0-0-0-0-1-0-0-0-0-0-0-0-0-0-0-0
30          .Current = val(ReadField(AddPointer(LastPoint), Data, 45)) '19
40          .WaitingReward = IIf(val(ReadField(AddPointer(LastPoint), Data, 45)), True, False) '0
50          .NpcIndexGiver = val(ReadField(AddPointer(LastPoint), Data, 45)) '218
60          .Timing = val(ReadField(AddPointer(LastPoint), Data, 45))

70          .CanDoThisOne = val(ReadField(AddPointer(LastPoint), Data, 45))
80          .OffererNpcIndex = val(ReadField(AddPointer(LastPoint), Data, 45))
90          .CanViewCampaignList = IIf(val(ReadField(AddPointer(LastPoint), Data, 45)) <> 0, True, False)
100         .StagesCompleted = val(ReadField(AddPointer(LastPoint), Data, 45))
           
110         If .Current > 0 Then
120             .CanDoThisOne = .Current

                Dim i           As Integer

130             ReDim .Stages(1 To Campaign(.Current).Properties.NumStages)
               
140             For i = 1 To Campaign(.Current).Properties.NumStages
150                 .Stages(i).Done = IIf(val(ReadField(AddPointer(LastPoint), Data, 45)) <> 0, True, False)
160                 .Stages(i).StageTiming = val(ReadField(AddPointer(LastPoint), Data, 45))
170                 .Stages(i).AmountTarget = val(ReadField(AddPointer(LastPoint), Data, 45)) 'NUEVO!
'170                 .Stages(i).AmountTargetNpc = val(ReadField(AddPointer(LastPoint), DATA, 45))
'180                 .Stages(i).AmountTargetUser = val(ReadField(AddPointer(LastPoint), DATA, 45))
'190                 .Stages(i).AmountTargetObj = val(ReadField(AddPointer(LastPoint), DATA, 45))
200                 .Stages(i).HaveToFoundPlace = IIf(val(ReadField(AddPointer(LastPoint), Data, 45)) <> 0, True, False)
210                 .Stages(i).ObjDelivered = IIf(val(ReadField(AddPointer(LastPoint), Data, 45)) <> 0, True, False)
220             Next i
230         End If

            'Debug.Print "Load Campaing Field counts: " & FieldCount(data, 45) & " must Be: " & (Campaign(UserList(UserIndex).Campaign.Current).Properties.NumStages * 6) + 8
240     End With
250 End If

    On Error GoTo 0
    Exit Sub

LoadUserCampaignData_Error:

    Call LogError("Error " & err.Number & " (" & err.Description & ") procedimiento LoadUserCampaignData Módulo modCampaign línea: " & Erl())

End Sub

Public Function SaveCampaignData(ByVal UserIndex As Integer) As clsFastString

10  On Error GoTo SaveCampaignData_Error

20  Set SaveCampaignData = New clsFastString

30  With UserList(UserIndex)
40      If .Campaign.Current > 0 Then
50          If Campaign(.Campaign.Current).Properties.FinishWhenDisconnect Then
60              SaveCampaignData.Clear
70              SaveCampaignData = SaveCampaignData.Value    'vbNullString
80          Else
90              With UserList(UserIndex).Campaign
                    'Dim finalString As String

100                 SaveCampaignData.Append CStr(.Current)
110                 SaveCampaignData.Append "-" & CStr(IIf(.WaitingReward, 1, 0))
120                 SaveCampaignData.Append "-" & CStr(.NpcIndexGiver)
130                 SaveCampaignData.Append "-" & CStr(.Timing)
140                 SaveCampaignData.Append "-" & CStr(.CanDoThisOne)
150                 SaveCampaignData.Append "-" & CStr(.OffererNpcIndex)
160                 SaveCampaignData.Append "-" & CStr(IIf(val(.CanViewCampaignList), 1, 0))
170                 SaveCampaignData.Append "-" & CStr(.StagesCompleted)

                    '8 strings

180                 If .Current > 0 Then
                        Dim i     As Integer

190                     For i = 1 To Campaign(.Current).Properties.NumStages

200                         SaveCampaignData.Append "-" & CStr(IIf(.Stages(i).Done, 1, 0))
210                         SaveCampaignData.Append "-" & CStr(.Stages(i).StageTiming)
220                         SaveCampaignData.Append "-" & CStr(.Stages(i).AmountTarget)

                            '190                         SaveCampaignData.Append "-" & CStr(.Stages(i).AmountTargetNpc)
                            '200                         SaveCampaignData.Append "-" & CStr(.Stages(i).AmountTargetUser)
                            '210                         SaveCampaignData.Append "-" & CStr(.Stages(i).AmountTargetObj)
230                         SaveCampaignData.Append "-" & CStr(IIf(.Stages(i).HaveToFoundPlace, 1, 0))
240                         SaveCampaignData.Append "-" & CStr(IIf(.Stages(i).ObjDelivered, 1, 0))
                            '6 strings por cada STAGE
250                     Next i
260                 End If

270             End With
280         End If
290     Else
300         SaveCampaignData.Clear
310         .Campaign.CampaignUnfinishSaved = SaveCampaignData.Value
320     End If

        'Debug.Print "SAVE Campaing Field counts: " & FieldCount(finalString, 45) & " must Be: " & (Campaign(UserList(UserIndex).Campaign.Current).Properties.NumStages * 6) + 8
330     .Campaign.CampaignUnfinishSaved = SaveCampaignData.Value

340 End With

350 On Error GoTo 0
360 Exit Function

SaveCampaignData_Error:

370 Call LogError("Error " & err.Number & " (" & err.Description & ") procedimiento SaveCampaignData Módulo modCampaign línea: " & Erl())

End Function

Public Sub ReloadStageTimed(ByVal UserIndex As Integer)

Dim i                           As Integer

    On Error GoTo ReloadStageTimed_Error

10  With UserList(UserIndex).Campaign

20      For i = 1 To Campaign(.Current).Properties.NumStages
30          If Not .Stages(i).Done And .Stages(i).StageTiming > 0 Then
40              .Stages(i).StageTiming = 0
50              .Stages(i).AmountTarget = 0 'NUEVO! 21/12/2020
'50              .Stages(i).AmountTargetNpc = 0
'60              .Stages(i).AmountTargetUser = 0
'70              .Stages(i).AmountTargetObj = 0
80              .Stages(i).ObjDelivered = False
90              .Stages(i).HaveToFoundPlace = val(Campaign(.Current).Stages(i).Objetives.TargetLocation.Trigger <> 0) Or (val(Campaign(.Current).Stages(i).Objetives.TargetLocation.posX <> 0) And val(Campaign(.Current).Stages(i).Objetives.TargetLocation.posY <> 0) And val(Campaign(.Current).Stages(i).Objetives.TargetLocation.Map <> 0))
100         End If
110     Next i

120     Call WriteConsoleMsg(UserIndex, "{999} Se ha reiniciado el objetivo.", FontTypeNames.FONTTYPE_CAMPAIGN)    '¡Se ha agotado el tiempo para cumplir el objetivo!
130     Call WriteUpdateCampaignInfo(UserIndex, .Current)

140 End With

    On Error GoTo 0
    Exit Sub

ReloadStageTimed_Error:

    Call LogError("Error " & err.Number & " (" & err.Description & ") procedimiento ReloadStageTimed Módulo modCampaign línea: " & Erl())

End Sub
Tengo uno recontra mil mejorado pero está muy adaptado a Bender.

Deberías laburar mucho en todo lo que es protocolo y eso, pero bueno, te lo dejo por si te sirve, porque es basado justamente en este que pedís:
Creo que el men busca los archvios que subio xprocess a lo ultimo
 

Lukih

Soñador
Colaborador
Tengo uno recontra mil mejorado pero está muy adaptado a Bender.

Deberías laburar mucho en todo lo que es protocolo y eso, pero bueno, te lo dejo por si te sirve, porque es basado justamente en este que pedís:
Muchas gracias por tu aporte, voy a leérmelo para ver que cositas lindas le hiciste.

Creo que el men busca los archivos que subio xprocess a lo ultimo
Si, la idea original del post era ver si encontraba los formularios para no tener que armarlos de 0 pero con esto que me dejó @About voy a tener para divertirme.
 

About

Director del Proyecto
La verdad, que me faltó la mitad del módulo porque no me dejó subirlo entero. Ahora voy a ver si te lo puedo adjuntar en un mensaje, porque la otra noche me pudrí de intentarlo.

El sistema tiene cosas como por ejemplo, el hecho de poder hacer cualquier objetivo en cualquier orden, o en un orden específico (a elección)
Además, tiene nuevas recompensas, como por ejemplo, convertirte en alguna facción al finalizar alguna misión (lo cual está buenísimo para que ser armada o legión, no sea sólo matar gente, sino hacer una serie de objetivos roleros)
También estuve optimizando todo el sistema en general, aunque hay muchísimas cosas que no me gustan y que cambiaría totalmente, pero conlleva muchísimo trabajo la verdad, porque es un sistema complejo de entender, por lo extenso más que nada. Pero por fortuna, éste sistema estaba TAN prolijo hecho desde una base, que cuando lo implementé hará 4 o 5 años atrás (no se si más) aprendí muchísimo haciéndolo. El sistema en general, me cambió totalmente la forma de programar en vb6 y me enseño muchas cosas.
Post automatically merged:

Acá te dejo el link del módulo https://www.mediafire.com/file/0p4yomda6cf2d6l/mod_Campaing.bas/file, después voy a ver si te puedo pasar las funciones aisladas que van chekeando que si estás en misión vaya acoplando los objetivos según corresponda, y vaya contabilizandolo.
Post automatically merged:

'[/About] By xpproces09
Private Sub HandleNCWorkRightClick(ByVal UserIndex As Integer)

Dim x As Integer
Dim Y As Integer

On Error GoTo HandleNCWorkRightClick_Error

10 With UserList(UserIndex)

20 x = .IncomingData.ReadInteger()
30 Y = .IncomingData.ReadInteger()

40 If .flags.Muerto <> 0 Or .flags.Descansar Or .flags.Meditando Or Not InMapBounds(.pos.Map, x, Y) Then Exit Sub

50 If Not InRangoVision(UserIndex, x, Y) Then
60 Call WritePosUpdate(UserIndex)
70 Exit Sub
80 End If

90 .Campaign.CanDoThisOne = 0
100 .Campaign.OffererNpcIndex = 0

110 Call CancelExit(UserIndex)
120 Call RightClickEvents(UserIndex, .pos.Map, x, Y)

130 End With

On Error GoTo 0
Exit Sub

HandleNCWorkRightClick_Error:

Call LogProtocolError("Error " & err.Number & " Descripción: & (" & err.Description & ") del procedimiento HandleNCWorkRightClick del Módulo Protocol" & " En la linea: " & Erl)

End Sub

'[/About] By xpproces09
Private Sub HandleNCRequestCampaign(ByVal UserIndex As Integer)

On Error GoTo HandleNCRequestCampaign_Error

10 With UserList(UserIndex)

20 If .flags.TargetNPC = 0 Then
30 Call WriteConsoleMsg(UserIndex, "{470}", FontTypeNames.FONTTYPE_INFO)
40 Exit Sub
50 End If

60 If .flags.Muerto <> 0 Then
70 Call WriteConsoleMsg(UserIndex, "{1330}", FontTypeNames.FONTTYPE_INFO)
80 Exit Sub
90 End If

100 If Distancia(NpcList(.flags.TargetNPC).pos, .pos) > 3 Then
110 Call WriteConsoleMsg(UserIndex, "{04}", FontTypeNames.FONTTYPE_INFO)
120 Exit Sub
130 End If

Dim Text As String
140 Text = "¡No te he ofrecido ninguna misión!"

150 If .Campaign.CanDoThisOne > 0 Then
160 If .Campaign.OffererNpcIndex = .flags.TargetNPC Then
170 Call WriteGiveCampaign(UserIndex, .Campaign.CanDoThisOne)
180 Else
190 Call ShowCampaignChat(UserIndex, .flags.TargetNPC, Text)
200 End If
210 Else
220 Call ShowCampaignChat(UserIndex, .flags.TargetNPC, Text)
230 End If
240 End With

On Error GoTo 0
Exit Sub

HandleNCRequestCampaign_Error:

Call LogError("Error " & err.Number & " (" & err.Description & ") procedimiento HandleNCRequestCampaign Módulo Protocol línea: " & Erl())

End Sub

'[/About] By xpproces09
Private Sub HandleNCAcceptCampaign(ByVal UserIndex As Integer)

Call CampaignBegin(UserIndex)

End Sub

'[/About] By xpproces09
Private Sub HandleNCRejectCampaign(ByVal UserIndex As Integer)

Call FinishUncompletedCampaign(UserIndex, CampaignFailReason.Reject)

End Sub

'[/About] By xpproces09
Private Sub HandleNCLeaveCampaign(ByVal UserIndex As Integer)

With UserList(UserIndex)
'Call .incomingData.ReadByte

If .Campaign.Current <> 0 Then
Call FinishUncompletedCampaign(UserIndex, CampaignFailReason.Leave)
Else
Call WriteConsoleMsg(UserIndex, "{1015}", FontTypeNames.FONTTYPE_CAMPAIGN)
End If

End With

End Sub

'[/About] By xpproces09
Private Sub HandleNCRequestCampaignInfo(ByVal UserIndex As Integer)

With UserList(UserIndex)

If .Campaign.Current <> 0 Then
Call WriteGiveCampaignInfo(UserIndex, .Campaign.Current)
Else

Call WriteConsoleMsg(UserIndex, "{1015}", FontTypeNames.FONTTYPE_CAMPAIGN)
Call WriteGiveCampaignBook(UserIndex)
End If

End With

End Sub

'[/About] By xpproces09
Private Sub HandleNCRequestReward(ByVal UserIndex As Integer)

On Error GoTo HandleNCRequestReward_Error

10 With UserList(UserIndex)

20 If .flags.TargetNPC = 0 Then
30 Call WriteConsoleMsg(UserIndex, "{470}", FontTypeNames.FONTTYPE_INFO)
40 Exit Sub
50 End If

60 If .flags.Muerto <> 0 Then
70 Call WriteConsoleMsg(UserIndex, "{1330}", FontTypeNames.FONTTYPE_INFO)
80 Exit Sub
90 End If

100 If Distancia(NpcList(.flags.TargetNPC).pos, .pos) > 3 Then
110 Call WriteConsoleMsg(UserIndex, "{04}", FontTypeNames.FONTTYPE_INFO)
120 Exit Sub
130 End If

Dim Text As String

140 If .Campaign.Current <> 0 Then
150 If .Campaign.NpcIndexGiver = NpcList(.flags.TargetNPC).ID Then
160 If .Campaign.WaitingReward Then
170 Call FinishCompletedCampaign(UserIndex, .flags.TargetNPC)
180 Else
190 Text = "No has completado tus objetivos!"
200 Call ShowCampaignChat(UserIndex, .flags.TargetNPC, Text)
210 End If
220 Else
230 Text = "No estás haciendo una misión para mi!"
240 Call ShowCampaignChat(UserIndex, .flags.TargetNPC, Text)
250 End If
260 Else
270 Call WriteConsoleMsg(UserIndex, "{1015}", FontTypeNames.FONTTYPE_CAMPAIGN)
280 End If

290 End With

On Error GoTo 0
Exit Sub

HandleNCRequestReward_Error:

Call LogProtocolError("Error " & err.Number & " Descripción: & (" & err.Description & ") del procedimiento HandleNCRequestReward del Módulo Protocol" & " En la linea: " & Erl)

End Sub

'[/About] By xpproces09
Private Sub HandleNCRequestKeyWordFrm(ByVal UserIndex As Integer)

Dim Text As String

With UserList(UserIndex)

If .flags.TargetNPC = 0 Then
Call WriteConsoleMsg(UserIndex, "{470}", FontTypeNames.FONTTYPE_INFO)
Exit Sub
End If

If .flags.Muerto <> 0 Then
Call WriteConsoleMsg(UserIndex, "{1330}", FontTypeNames.FONTTYPE_INFO)
Exit Sub
End If

If Distancia(NpcList(.flags.TargetNPC).pos, .pos) > 3 Then
Call WriteConsoleMsg(UserIndex, "{04}", FontTypeNames.FONTTYPE_INFO)
Exit Sub
End If

Text = "{112}" '¡No tienes que entregarme ninguna respuesta!

If .Campaign.Current <> 0 Then '@ ¿Está haciendo misión?
Dim i As Integer

For i = 1 To Campaign(.Campaign.Current).Properties.NumStages
If Campaign(.Campaign.Current).Stages(i).Objetives.TargetNPC.Index = NpcList(.flags.TargetNPC).ID Then '@ ¿Le hizo clic al npc indicado?
If StrComp(Campaign(.Campaign.Current).Stages(i).Objetives.KeyWord, vbNullString) <> 0 Then '@ ¿Escribió algo el cara de pija?
Call WriteRequestKeyword(UserIndex)
ElseIf i = Campaign(.Campaign.Current).Properties.NumStages Then
Call ShowCampaignChat(UserIndex, .flags.TargetNPC, Text)
End If
ElseIf i = Campaign(.Campaign.Current).Properties.NumStages Then
Call ShowCampaignChat(UserIndex, .flags.TargetNPC, Text)
End If
Next i
Else
Call WriteConsoleMsg(UserIndex, "{1015}", FontTypeNames.FONTTYPE_CAMPAIGN)
End If

End With

End Sub

'[/About] By xpproces09
Private Sub HandleNCGiveKeyWord(ByVal UserIndex As Integer)

Dim KeyWord As String

With UserList(UserIndex)

KeyWord = .IncomingData.ReadASCIIString()

If .flags.TargetNPC > 0 Then
Call CheckCampaignKeyWord(UserIndex, .flags.TargetNPC, KeyWord)
Else
Call WriteConsoleMsg(UserIndex, "{470}", FontTypeNames.FONTTYPE_INFO)
End If

End With

End Sub

'[/About] By xpproces09
Private Sub HandleNCRequestCampaignList(ByVal UserIndex As Integer)

With UserList(UserIndex)

If .flags.TargetNPC = 0 Then
Call WriteConsoleMsg(UserIndex, "{101}", FontTypeNames.FONTTYPE_INFO) 'Debes hacer clic sobre el NPC antes
Exit Sub
End If

If .flags.Muerto <> 0 Then
Call WriteConsoleMsg(UserIndex, "{00}", FontTypeNames.FONTTYPE_INFO) '¡Estás muerto!
Exit Sub
End If

If Distancia(NpcList(.flags.TargetNPC).pos, .pos) > 3 Then
Call WriteConsoleMsg(UserIndex, "{04}", FontTypeNames.FONTTYPE_INFO) 'Estás demasiado lejos.
Exit Sub
End If

If StrComp(NpcList(.flags.TargetNPC).CampaignsGiven, vbNullString) <> 0 Then
If .Campaign.CanViewCampaignList Then
If .Campaign.OffererNpcIndex = .flags.TargetNPC Then
Call WriteGiveCampaignList(UserIndex, .Campaign.OffererNpcIndex)
Else
Call ShowCampaignChat(UserIndex, .flags.TargetNPC, "{1016}") '¡No te he ofrecido ver mis misones!
End If
Else
Call ShowCampaignChat(UserIndex, .flags.TargetNPC, "{1016}") '¡No te he ofrecido ver mis misones!
End If
Else
Call WriteConsoleMsg(UserIndex, "{1013}", FontTypeNames.FONTTYPE_CAMPAIGN) 'El Npc no tiene misiones para ofrecerte.
End If
End With

End Sub

'[/About] By xpproces09
Private Sub HandleNCRequestCampaignBook(ByVal UserIndex As Integer)

With UserList(UserIndex)
'Call .incomingData.ReadByte
If .Campaign.Current = 0 Then
If Len(.Campaign.CampaignsHasDone) = 0 Then
'Si quieres conseguir una misión, ve con los personajes que tienen un signo de pregunta sobre su cabeza y haz DOBLE CLIC 'DERECHO' sobre él.
Call WriteConsoleMsg(UserIndex, "{1014}", FontTypeNames.FONTTYPE_CAMPAIGN)
Exit Sub
Else
Call WriteGiveCampaignBook(UserIndex)
End If
Else
Call WriteGiveCampaignBook(UserIndex)
End If
End With

End Sub

'[/About] By xpproces09
Private Sub HandleNCAcceptCampaignFromList(ByVal UserIndex As Integer)

Dim Number As Integer
Dim CampaignNumber As Integer
Dim Campaigns As String

With UserList(UserIndex)

Number = .IncomingData.ReadInteger
Campaigns = WhichOnes(UserIndex, .Campaign.OffererNpcIndex)
CampaignNumber = val(ReadField(Number, Campaigns, 45))
.Campaign.CanDoThisOne = CampaignNumber

If .Campaign.Current > 0 Then
Call WriteConsoleMsg(UserIndex, "Ya estás en una misión. No puedes aceptar otra. Para abandonar tu misión actual, ve al botón 'Misiones' y presiona 'Abandonar Mision', o bien coloca /ABANDONARQUEST", FontTypeNames.FONTTYPE_CAMPAIGN)
Exit Sub
Else
Call CampaignBegin(UserIndex)
End If

End With

End Sub
Post automatically merged:

Ahí te dejé una parte del protolo server-side
 
Última edición:
Arriba