Jump to content
Search In
  • More options...
Find results that contain...
Find results in...

[EO] Alatar's Quest System v1.2


Alatar
 Share

Recommended Posts

  • Replies 703
  • Created
  • Last Reply

Top Posters In This Topic

it tells me "Compile error:  Method or data member not found"  Then it highlights
.Quest

in

If NPC(npcNum).Quest = YES Then

under the function

Function CanPlayerAttackNpc(ByVal attacker As Long, ByVal mapNpcNum As Long, Optional ByVal IsSpell As Boolean = False) As Boolean

>! ```
Option Explicit
>! ' ################################
' ##      Basic Calculations    ##
' ################################
>! Function GetPlayerMaxVital(ByVal Index As Long, ByVal Vital As Vitals) As Long
    If Index > MAX_PLAYERS Then Exit Function
    Select Case Vital
        Case HP
            Select Case GetPlayerClass(Index)
                Case 1 ' Warrior
                    GetPlayerMaxVital = ((GetPlayerLevel(Index) / 2) + (GetPlayerStat(Index, Endurance) / 2)) * 15 + 150
                Case 2 ' Mage
                    GetPlayerMaxVital = ((GetPlayerLevel(Index) / 2) + (GetPlayerStat(Index, Endurance) / 2)) * 5 + 65
                Case Else ' Anything else - Warrior by default
                    GetPlayerMaxVital = ((GetPlayerLevel(Index) / 2) + (GetPlayerStat(Index, Endurance) / 2)) * 15 + 150
            End Select
        Case MP
            Select Case GetPlayerClass(Index)
                Case 1 ' Warrior
                    GetPlayerMaxVital = ((GetPlayerLevel(Index) / 2) + (GetPlayerStat(Index, Intelligence) / 2)) * 5 + 25
                Case 2 ' Mage
                    GetPlayerMaxVital = ((GetPlayerLevel(Index) / 2) + (GetPlayerStat(Index, Intelligence) / 2)) * 30 + 85
                Case Else ' Anything else - Warrior by default
                    GetPlayerMaxVital = ((GetPlayerLevel(Index) / 2) + (GetPlayerStat(Index, Intelligence) / 2)) * 5 + 25
            End Select
    End Select
End Function
>! Function GetPlayerVitalRegen(ByVal Index As Long, ByVal Vital As Vitals) As Long
    Dim i As Long
>!     ' Prevent subscript out of range
    If IsPlaying(Index) = False Or Index <= 0 Or Index > MAX_PLAYERS Then
        GetPlayerVitalRegen = 0
        Exit Function
    End If
>!     Select Case Vital
        Case HP
            i = (GetPlayerStat(Index, Stats.Willpower) * 0.8) + 6
        Case MP
            i = (GetPlayerStat(Index, Stats.Willpower) / 4) + 12.5
    End Select
>!     If i < 2 Then i = 2
    GetPlayerVitalRegen = i
End Function
>! Function GetPlayerDamage(ByVal Index As Long) As Long
    Dim weaponNum As Long

    GetPlayerDamage = 0
>!     ' Check for subscript out of range
    If IsPlaying(Index) = False Or Index <= 0 Or Index > MAX_PLAYERS Then
        Exit Function
    End If
    If GetPlayerEquipment(Index, Weapon) > 0 Then
        weaponNum = GetPlayerEquipment(Index, Weapon)
        GetPlayerDamage = 0.085 * 5 * GetPlayerStat(Index, Strength) * Item(weaponNum).Data2 + (GetPlayerLevel(Index) / 5)
    Else
        GetPlayerDamage = 0.085 * 5 * GetPlayerStat(Index, Strength) + (GetPlayerLevel(Index) / 5)
    End If
>! End Function
>! Function GetNpcMaxVital(ByVal npcNum As Long, ByVal Vital As Vitals) As Long
    Dim x As Long
>!     ' Prevent subscript out of range
    If npcNum <= 0 Or npcNum > MAX_NPCS Then
        GetNpcMaxVital = 0
        Exit Function
    End If
>!     Select Case Vital
        Case HP
            GetNpcMaxVital = NPC(npcNum).HP
        Case MP
            GetNpcMaxVital = 30 + (NPC(npcNum).Stat(Intelligence) * 10) + 2
    End Select
>! End Function
>! Function GetNpcVitalRegen(ByVal npcNum As Long, ByVal Vital As Vitals) As Long
    Dim i As Long
>!     'Prevent subscript out of range
    If npcNum <= 0 Or npcNum > MAX_NPCS Then
        GetNpcVitalRegen = 0
        Exit Function
    End If
>!     Select Case Vital
        Case HP
            i = (NPC(npcNum).Stat(Stats.Willpower) * 0.8) + 6
        Case MP
            i = (NPC(npcNum).Stat(Stats.Willpower) / 4) + 12.5
    End Select

    GetNpcVitalRegen = i
>! End Function
>! Function GetNpcDamage(ByVal npcNum As Long) As Long
    GetNpcDamage = 0.085 * 5 * NPC(npcNum).Stat(Stats.Strength) * NPC(npcNum).Damage + (NPC(npcNum).Level / 5)
End Function
>! ' ###############################
' ##      Luck-based rates    ##
' ###############################
>! Public Function CanPlayerBlock(ByVal Index As Long) As Boolean
Dim rate As Long
Dim rndNum As Long
>!     CanPlayerBlock = False
>!     rate = 0
    ' TODO : make it based on shield lulz
End Function
>! Public Function CanPlayerCrit(ByVal Index As Long) As Boolean
Dim rate As Long
Dim rndNum As Long
>!     CanPlayerCrit = False
>!     rate = GetPlayerStat(Index, Agility) / 52.08
    rndNum = RAND(1, 100)
    If rndNum <= rate Then
        CanPlayerCrit = True
    End If
End Function
>! Public Function CanPlayerDodge(ByVal Index As Long) As Boolean
Dim rate As Long
Dim rndNum As Long
>!     CanPlayerDodge = False
>!     rate = GetPlayerStat(Index, Agility) / 83.3
    rndNum = RAND(1, 100)
    If rndNum <= rate Then
        CanPlayerDodge = True
    End If
End Function
>! Public Function CanPlayerParry(ByVal Index As Long) As Boolean
Dim rate As Long
Dim rndNum As Long
>!     CanPlayerParry = False
>!     rate = GetPlayerStat(Index, Strength) * 0.25
    rndNum = RAND(1, 100)
    If rndNum <= rate Then
        CanPlayerParry = True
    End If
End Function
>! Public Function CanNpcBlock(ByVal npcNum As Long) As Boolean
Dim rate As Long
Dim rndNum As Long
>!     CanNpcBlock = False
>!     rate = 0
    ' TODO : make it based on shield lol
End Function
>! Public Function CanNpcCrit(ByVal npcNum As Long) As Boolean
Dim rate As Long
Dim rndNum As Long
>!     CanNpcCrit = False
>!     rate = NPC(npcNum).Stat(Stats.Agility) / 52.08
    rndNum = RAND(1, 100)
    If rndNum <= rate Then
        CanNpcCrit = True
    End If
End Function
>! Public Function CanNpcDodge(ByVal npcNum As Long) As Boolean
Dim rate As Long
Dim rndNum As Long
>!     CanNpcDodge = False
>!     rate = NPC(npcNum).Stat(Stats.Agility) / 83.3
    rndNum = RAND(1, 100)
    If rndNum <= rate Then
        CanNpcDodge = True
    End If
End Function
>! Public Function CanNpcParry(ByVal npcNum As Long) As Boolean
Dim rate As Long
Dim rndNum As Long
>!     CanNpcParry = False
>!     rate = NPC(npcNum).Stat(Stats.Strength) * 0.25
    rndNum = RAND(1, 100)
    If rndNum <= rate Then
        CanNpcParry = True
    End If
End Function
>! ' ###################################
' ##      Player Attacking NPC    ##
' ###################################
>! Public Sub TryPlayerAttackNpc(ByVal Index As Long, ByVal mapNpcNum As Long)
Dim blockAmount As Long
Dim npcNum As Long
Dim mapNum As Long
Dim Damage As Long
>!     Damage = 0
>!     ' Can we attack the npc?
    If CanPlayerAttackNpc(Index, mapNpcNum) Then

        mapNum = GetPlayerMap(Index)
        npcNum = MapNpc(mapNum).NPC(mapNpcNum).Num

        ' check if NPC can avoid the attack
        If CanNpcDodge(npcNum) Then
            SendActionMsg mapNum, "Dodge!", Pink, 1, (MapNpc(mapNum).NPC(mapNpcNum).x * 32), (MapNpc(mapNum).NPC(mapNpcNum).y * 32)
            Exit Sub
        End If
        If CanNpcParry(npcNum) Then
            SendActionMsg mapNum, "Parry!", Pink, 1, (MapNpc(mapNum).NPC(mapNpcNum).x * 32), (MapNpc(mapNum).NPC(mapNpcNum).y * 32)
            Exit Sub
        End If
>!         ' Get the damage we can do
        Damage = GetPlayerDamage(Index)

        ' if the npc blocks, take away the block amount
        blockAmount = CanNpcBlock(mapNpcNum)
        Damage = Damage - blockAmount

        ' take away armour
        Damage = Damage - RAND(1, (NPC(npcNum).Stat(Stats.Agility) * 2))
        ' randomise from 1 to max hit
        Damage = RAND(1, Damage)

        ' * 1.5 if it's a crit!
        If CanPlayerCrit(Index) Then
            Damage = Damage * 1.5
            SendActionMsg mapNum, "Critical!", BrightCyan, 1, (GetPlayerX(Index) * 32), (GetPlayerY(Index) * 32)
        End If

        If Damage > 0 Then
            Call PlayerAttackNpc(Index, mapNpcNum, Damage)
        Else
            Call PlayerMsg(Index, "Your attack does nothing.", BrightRed)
        End If
    End If
End Sub
>! Public Function CanPlayerAttackNpc(ByVal attacker As Long, ByVal mapNpcNum As Long, Optional ByVal IsSpell As Boolean = False) As Boolean
    Dim mapNum As Long
    Dim npcNum As Long
    Dim NpcX As Long
    Dim NpcY As Long
    Dim attackspeed As Long
>!     ' Check for subscript out of range
    If IsPlaying(attacker) = False Or mapNpcNum <= 0 Or mapNpcNum > MAX_MAP_NPCS Then
        Exit Function
    End If
>!     ' Check for subscript out of range
    If MapNpc(GetPlayerMap(attacker)).NPC(mapNpcNum).Num <= 0 Then
        Exit Function
    End If
>!     mapNum = GetPlayerMap(attacker)
    npcNum = MapNpc(mapNum).NPC(mapNpcNum).Num

    ' Make sure the npc isn't already dead
    If MapNpc(mapNum).NPC(mapNpcNum).Vital(Vitals.HP) <= 0 Then
        If NPC(MapNpc(mapNum).NPC(mapNpcNum).Num).Behaviour <> NPC_BEHAVIOUR_FRIENDLY Then
            If NPC(MapNpc(mapNum).NPC(mapNpcNum).Num).Behaviour <> NPC_BEHAVIOUR_SHOPKEEPER Then
                Exit Function
            End If
        End If
    End If
>!     ' Make sure they are on the same map
    If IsPlaying(attacker) Then

        ' exit out early
        If IsSpell Then
            If npcNum > 0 Then
                If NPC(npcNum).Behaviour <> NPC_BEHAVIOUR_FRIENDLY And NPC(npcNum).Behaviour <> NPC_BEHAVIOUR_SHOPKEEPER Then
                    CanPlayerAttackNpc = True
                    Exit Function
                End If
            End If
        End If
>!         ' attack speed from weapon
        If GetPlayerEquipment(attacker, Weapon) > 0 Then
            attackspeed = Item(GetPlayerEquipment(attacker, Weapon)).Speed
        Else
            attackspeed = 1000
        End If
>!         If npcNum > 0 And GetTickCount > TempPlayer(attacker).AttackTimer + attackspeed Then
            ' Check if at same coordinates
            Select Case GetPlayerDir(attacker)
                Case DIR_UP
                    NpcX = MapNpc(mapNum).NPC(mapNpcNum).x
                    NpcY = MapNpc(mapNum).NPC(mapNpcNum).y + 1
                Case DIR_DOWN
                    NpcX = MapNpc(mapNum).NPC(mapNpcNum).x
                    NpcY = MapNpc(mapNum).NPC(mapNpcNum).y - 1
                Case DIR_LEFT
                    NpcX = MapNpc(mapNum).NPC(mapNpcNum).x + 1
                    NpcY = MapNpc(mapNum).NPC(mapNpcNum).y
                Case DIR_RIGHT
                    NpcX = MapNpc(mapNum).NPC(mapNpcNum).x - 1
                    NpcY = MapNpc(mapNum).NPC(mapNpcNum).y
            End Select
>!             If NpcX = GetPlayerX(attacker) Then
                If NpcY = GetPlayerY(attacker) Then
                    If NPC(npcNum).Behaviour <> NPC_BEHAVIOUR_FRIENDLY And NPC(npcNum).Behaviour <> NPC_BEHAVIOUR_SHOPKEEPER Then
                        CanPlayerAttackNpc = True
                    Else
                        'ALATAR
                        If NPC(npcNum).Behaviour = NPC_BEHAVIOUR_FRIENDLY Then
                            Call CheckTasks(attacker, QUEST_TYPE_GOTALK, npcNum)
                            Call CheckTasks(attacker, QUEST_TYPE_GOGIVE, npcNum)
                            Call CheckTasks(attacker, QUEST_TYPE_GOGET, npcNum)

                            If NPC(npcNum).Quest = YES Then
                                If CanStartQuest(attacker, NPC(npcNum).QuestNum) Then
                                    'if can start show the request message (chat1)
                                    QuestMessage attacker, NPC(npcNum).QuestNum, Trim$(Quest(NPC(npcNum).QuestNum).Chat(1)), NPC(npcNum).QuestNum
                                    Exit Function
                                End If
                                If QuestInProgress(attacker, NPC(npcNum).QuestNum) Then
                                    'if the quest is in progress show the meanwhile message (chat2)
                                    PlayerMsg attacker, Trim$(NPC(npcNum).Name) + ": " + Trim$(Quest(NPC(npcNum).QuestNum).Chat(2)), BrightGreen
                                    'QuestMessage attacker, NPC(npcNum).QuestNum, Trim$(Quest(NPC(npcNum).QuestNum).Chat(2)), 0
                                    Exit Function
                                End If
                            End If

                        If NPC(npcNum).Quest = NO Then
                                If NPC(npcNum).Convo = False Then
                                  If Len(Trim$(NPC(npcNum).AttackSay)) > 0 Then
                                    PlayerMsg attacker, Trim$(NPC(npcNum).Name) + ": " + Trim$(Quest(NPC(npcNum).QuestNum).Chat(2)), BrightGreen
                                  End If
                                Else
                                    InitChat attacker, mapNum, mapNpcNum
                                End If
                                Exit Function
                            End If
                        End If

                    End If
                End If
            End If
        End If
    End If
>! End Function
>! Public Sub PlayerAttackNpc(ByVal attacker As Long, ByVal mapNpcNum As Long, ByVal Damage As Long, Optional ByVal spellnum As Long, Optional ByVal overTime As Boolean = False)
    Dim Name As String
    Dim exp As Long
    Dim n As Long
    Dim i As Long
    Dim STR As Long
    Dim DEF As Long
    Dim mapNum As Long
    Dim npcNum As Long
    Dim Buffer As clsBuffer
>!     ' Check for subscript out of range
    If IsPlaying(attacker) = False Or mapNpcNum <= 0 Or mapNpcNum > MAX_MAP_NPCS Or Damage < 0 Then
        Exit Sub
    End If
>!     mapNum = GetPlayerMap(attacker)
    npcNum = MapNpc(mapNum).NPC(mapNpcNum).Num
    Name = Trim$(NPC(npcNum).Name)

    ' Check for weapon
    n = 0
>!     If GetPlayerEquipment(attacker, Weapon) > 0 Then
        n = GetPlayerEquipment(attacker, Weapon)
    End If

    ' set the regen timer
    TempPlayer(attacker).stopRegen = True
    TempPlayer(attacker).stopRegenTimer = GetTickCount
>!     If Damage >= MapNpc(mapNum).NPC(mapNpcNum).Vital(Vitals.HP) Then

        SendActionMsg GetPlayerMap(attacker), "-" & MapNpc(mapNum).NPC(mapNpcNum).Vital(Vitals.HP), BrightRed, 1, (MapNpc(mapNum).NPC(mapNpcNum).x * 32), (MapNpc(mapNum).NPC(mapNpcNum).y * 32)
        SendBlood GetPlayerMap(attacker), MapNpc(mapNum).NPC(mapNpcNum).x, MapNpc(mapNum).NPC(mapNpcNum).y

        ' send the sound
        If spellnum > 0 Then SendMapSound attacker, MapNpc(mapNum).NPC(mapNpcNum).x, MapNpc(mapNum).NPC(mapNpcNum).y, SoundEntity.seSpell, spellnum

        ' send animation
        If n > 0 Then
            If Not overTime Then
                If spellnum = 0 Then Call SendAnimation(mapNum, Item(GetPlayerEquipment(attacker, Weapon)).Animation, MapNpc(mapNum).NPC(mapNpcNum).x, MapNpc(mapNum).NPC(mapNpcNum).y)
            End If
        End If
>!         ' Calculate exp to give attacker
        exp = NPC(npcNum).exp
>!         ' Make sure we dont get less then 0
        If exp < 0 Then
            exp = 1
        End If
>!         ' in party?
        If TempPlayer(attacker).inParty > 0 Then
            ' pass through party sharing function
            Party_ShareExp TempPlayer(attacker).inParty, exp, attacker
        Else
            ' no party - keep exp for self
            GivePlayerEXP attacker, exp
        End If

        'Drop the goods if they get it
        n = Int(Rnd * NPC(npcNum).DropChance) + 1
>!         If n = 1 Then
            Call SpawnItem(NPC(npcNum).DropItem, NPC(npcNum).DropItemValue, mapNum, MapNpc(mapNum).NPC(mapNpcNum).x, MapNpc(mapNum).NPC(mapNpcNum).y)
        End If
>!         ' Now set HP to 0 so we know to actually kill them in the server loop (this prevents subscript out of range)
        MapNpc(mapNum).NPC(mapNpcNum).Num = 0
        MapNpc(mapNum).NPC(mapNpcNum).SpawnWait = GetTickCount
        MapNpc(mapNum).NPC(mapNpcNum).Vital(Vitals.HP) = 0

        ' clear DoTs and HoTs
        For i = 1 To MAX_DOTS
            With MapNpc(mapNum).NPC(mapNpcNum).DoT(i)
                .Spell = 0
                .Timer = 0
                .Caster = 0
                .StartTime = 0
                .Used = False
            End With

            With MapNpc(mapNum).NPC(mapNpcNum).HoT(i)
                .Spell = 0
                .Timer = 0
                .Caster = 0
                .StartTime = 0
                .Used = False
            End With
        Next
        Call CheckTasks(attacker, QUEST_TYPE_GOSLAY, npcNum)
        ' send death to the map
        Set Buffer = New clsBuffer
        Buffer.WriteLong SNpcDead
        Buffer.WriteLong mapNpcNum
        SendDataToMap mapNum, Buffer.ToArray()
        Set Buffer = Nothing

        'Loop through entire map and purge NPC from targets
        For i = 1 To Player_HighIndex
            If IsPlaying(i) And IsConnected(i) Then
                If Player(i).Map = mapNum Then
                    If TempPlayer(i).targetType = TARGET_TYPE_NPC Then
                        If TempPlayer(i).target = mapNpcNum Then
                            TempPlayer(i).target = 0
                            TempPlayer(i).targetType = TARGET_TYPE_NONE
                            SendTarget i
                        End If
                    End If
                End If
            End If
        Next
    Else
        ' NPC not dead, just do the damage
        MapNpc(mapNum).NPC(mapNpcNum).Vital(Vitals.HP) = MapNpc(mapNum).NPC(mapNpcNum).Vital(Vitals.HP) - Damage
>!         ' Check for a weapon and say damage
        SendActionMsg mapNum, "-" & Damage, BrightRed, 1, (MapNpc(mapNum).NPC(mapNpcNum).x * 32), (MapNpc(mapNum).NPC(mapNpcNum).y * 32)
        SendBlood GetPlayerMap(attacker), MapNpc(mapNum).NPC(mapNpcNum).x, MapNpc(mapNum).NPC(mapNpcNum).y

        ' send the sound
        If spellnum > 0 Then SendMapSound attacker, MapNpc(mapNum).NPC(mapNpcNum).x, MapNpc(mapNum).NPC(mapNpcNum).y, SoundEntity.seSpell, spellnum

        ' send animation
        If n > 0 Then
            If Not overTime Then
                If spellnum = 0 Then Call SendAnimation(mapNum, Item(GetPlayerEquipment(attacker, Weapon)).Animation, 0, 0, TARGET_TYPE_NPC, mapNpcNum)
            End If
        End If
>!         ' Set the NPC target to the player
        MapNpc(mapNum).NPC(mapNpcNum).targetType = 1 ' player
        MapNpc(mapNum).NPC(mapNpcNum).target = attacker
>!         ' Now check for guard ai and if so have all onmap guards come after'm
        If NPC(MapNpc(mapNum).NPC(mapNpcNum).Num).Behaviour = NPC_BEHAVIOUR_GUARD Then
            For i = 1 To MAX_MAP_NPCS
                If MapNpc(mapNum).NPC(i).Num = MapNpc(mapNum).NPC(mapNpcNum).Num Then
                    MapNpc(mapNum).NPC(i).target = attacker
                    MapNpc(mapNum).NPC(i).targetType = 1 ' player
                End If
            Next
        End If

        ' set the regen timer
        MapNpc(mapNum).NPC(mapNpcNum).stopRegen = True
        MapNpc(mapNum).NPC(mapNpcNum).stopRegenTimer = GetTickCount

        ' if stunning spell, stun the npc
        If spellnum > 0 Then
            If Spell(spellnum).StunDuration > 0 Then StunNPC mapNpcNum, mapNum, spellnum
            ' DoT
            If Spell(spellnum).Duration > 0 Then
                AddDoT_Npc mapNum, mapNpcNum, spellnum, attacker
            End If
        End If

        SendMapNpcVitals mapNum, mapNpcNum
    End If
>!     If spellnum = 0 Then
        ' Reset attack timer
        TempPlayer(attacker).AttackTimer = GetTickCount
    End If
End Sub
>! ' ###################################
' ##      NPC Attacking Player    ##
' ###################################
>! Public Sub TryNpcAttackPlayer(ByVal mapNpcNum As Long, ByVal Index As Long)
Dim mapNum As Long, npcNum As Long, blockAmount As Long, Damage As Long
>!     ' Can the npc attack the player?
    If CanNpcAttackPlayer(mapNpcNum, Index) Then
        mapNum = GetPlayerMap(Index)
        npcNum = MapNpc(mapNum).NPC(mapNpcNum).Num

        ' check if PLAYER can avoid the attack
        If CanPlayerDodge(Index) Then
            SendActionMsg mapNum, "Dodge!", Pink, 1, (Player(Index).x * 32), (Player(Index).y * 32)
            Exit Sub
        End If
        If CanPlayerParry(Index) Then
            SendActionMsg mapNum, "Parry!", Pink, 1, (Player(Index).x * 32), (Player(Index).y * 32)
            Exit Sub
        End If
>!         ' Get the damage we can do
        Damage = GetNpcDamage(npcNum)

        ' if the player blocks, take away the block amount
        blockAmount = CanPlayerBlock(Index)
        Damage = Damage - blockAmount

        ' take away armour
        Damage = Damage - RAND(1, (GetPlayerStat(Index, Agility) * 2))

        ' randomise for up to 10% lower than max hit
        Damage = RAND(1, Damage)

        ' * 1.5 if crit hit
        If CanNpcCrit(Index) Then
            Damage = Damage * 1.5
            SendActionMsg mapNum, "Critical!", BrightCyan, 1, (MapNpc(mapNum).NPC(mapNpcNum).x * 32), (MapNpc(mapNum).NPC(mapNpcNum).y * 32)
        End If
>!         If Damage > 0 Then
            Call NpcAttackPlayer(mapNpcNum, Index, Damage)
        End If
    End If
End Sub
>! Function CanNpcAttackPlayer(ByVal mapNpcNum As Long, ByVal Index As Long) As Boolean
    Dim mapNum As Long
    Dim npcNum As Long
>!     ' Check for subscript out of range
    If mapNpcNum <= 0 Or mapNpcNum > MAX_MAP_NPCS Or Not IsPlaying(Index) Then
        Exit Function
    End If
>!     ' Check for subscript out of range
    If MapNpc(GetPlayerMap(Index)).NPC(mapNpcNum).Num <= 0 Then
        Exit Function
    End If
>!     mapNum = GetPlayerMap(Index)
    npcNum = MapNpc(mapNum).NPC(mapNpcNum).Num
>!     ' Make sure the npc isn't already dead
    If MapNpc(mapNum).NPC(mapNpcNum).Vital(Vitals.HP) <= 0 Then
        Exit Function
    End If
>!     ' Make sure npcs dont attack more then once a second
    If GetTickCount < MapNpc(mapNum).NPC(mapNpcNum).AttackTimer + 1000 Then
        Exit Function
    End If
>!     ' Make sure we dont attack the player if they are switching maps
    If TempPlayer(Index).GettingMap = YES Then
        Exit Function
    End If
>!     MapNpc(mapNum).NPC(mapNpcNum).AttackTimer = GetTickCount
>!     ' Make sure they are on the same map
    If IsPlaying(Index) Then
        If npcNum > 0 Then
>!             ' Check if at same coordinates
            If (GetPlayerY(Index) + 1 = MapNpc(mapNum).NPC(mapNpcNum).y) And (GetPlayerX(Index) = MapNpc(mapNum).NPC(mapNpcNum).x) Then
                CanNpcAttackPlayer = True
            Else
                If (GetPlayerY(Index) - 1 = MapNpc(mapNum).NPC(mapNpcNum).y) And (GetPlayerX(Index) = MapNpc(mapNum).NPC(mapNpcNum).x) Then
                    CanNpcAttackPlayer = True
                Else
                    If (GetPlayerY(Index) = MapNpc(mapNum).NPC(mapNpcNum).y) And (GetPlayerX(Index) + 1 = MapNpc(mapNum).NPC(mapNpcNum).x) Then
                        CanNpcAttackPlayer = True
                    Else
                        If (GetPlayerY(Index) = MapNpc(mapNum).NPC(mapNpcNum).y) And (GetPlayerX(Index) - 1 = MapNpc(mapNum).NPC(mapNpcNum).x) Then
                            CanNpcAttackPlayer = True
                        End If
                    End If
                End If
            End If
        End If
    End If
End Function
>! Sub NpcAttackPlayer(ByVal mapNpcNum As Long, ByVal victim As Long, ByVal Damage As Long)
    Dim Name As String
    Dim exp As Long
    Dim mapNum As Long
    Dim i As Long
    Dim Buffer As clsBuffer
>!     ' Check for subscript out of range
    If mapNpcNum <= 0 Or mapNpcNum > MAX_MAP_NPCS Or IsPlaying(victim) = False Then
        Exit Sub
    End If
>!     ' Check for subscript out of range
    If MapNpc(GetPlayerMap(victim)).NPC(mapNpcNum).Num <= 0 Then
        Exit Sub
    End If
>!     mapNum = GetPlayerMap(victim)
    Name = Trim$(NPC(MapNpc(mapNum).NPC(mapNpcNum).Num).Name)

    ' Send this packet so they can see the npc attacking
    Set Buffer = New clsBuffer
    Buffer.WriteLong SNpcAttack
    Buffer.WriteLong mapNpcNum
    SendDataToMap mapNum, Buffer.ToArray()
    Set Buffer = Nothing

    If Damage <= 0 Then
        Exit Sub
    End If

    ' set the regen timer
    MapNpc(mapNum).NPC(mapNpcNum).stopRegen = True
    MapNpc(mapNum).NPC(mapNpcNum).stopRegenTimer = GetTickCount
>!     If Damage >= GetPlayerVital(victim, Vitals.HP) Then
        ' Say damage
        SendActionMsg GetPlayerMap(victim), "-" & GetPlayerVital(victim, Vitals.HP), BrightRed, 1, (GetPlayerX(victim) * 32), (GetPlayerY(victim) * 32)

        ' send the sound
        SendMapSound victim, GetPlayerX(victim), GetPlayerY(victim), SoundEntity.seNpc, MapNpc(mapNum).NPC(mapNpcNum).Num

        ' kill player
        KillPlayer victim

        ' Player is dead
        Call GlobalMsg(GetPlayerName(victim) & " has been killed by " & Name, BrightRed)
>!         ' Set NPC target to 0
        MapNpc(mapNum).NPC(mapNpcNum).target = 0
        MapNpc(mapNum).NPC(mapNpcNum).targetType = 0
    Else
        ' Player not dead, just do the damage
        Call SetPlayerVital(victim, Vitals.HP, GetPlayerVital(victim, Vitals.HP) - Damage)
        Call SendVital(victim, Vitals.HP)
        Call SendAnimation(mapNum, NPC(MapNpc(GetPlayerMap(victim)).NPC(mapNpcNum).Num).Animation, 0, 0, TARGET_TYPE_PLAYER, victim)

        ' send vitals to party if in one
        If TempPlayer(victim).inParty > 0 Then SendPartyVitals TempPlayer(victim).inParty, victim

        ' send the sound
        SendMapSound victim, GetPlayerX(victim), GetPlayerY(victim), SoundEntity.seNpc, MapNpc(mapNum).NPC(mapNpcNum).Num

        ' Say damage
        SendActionMsg GetPlayerMap(victim), "-" & Damage, BrightRed, 1, (GetPlayerX(victim) * 32), (GetPlayerY(victim) * 32)
        SendBlood GetPlayerMap(victim), GetPlayerX(victim), GetPlayerY(victim)

        ' set the regen timer
        TempPlayer(victim).stopRegen = True
        TempPlayer(victim).stopRegenTimer = GetTickCount
    End If
>! End Sub
>! ' ###################################
' ##    Player Attacking Player    ##
' ###################################
>! Public Sub TryPlayerAttackPlayer(ByVal attacker As Long, ByVal victim As Long)
Dim blockAmount As Long
Dim npcNum As Long
Dim mapNum As Long
Dim Damage As Long
>!     Damage = 0
>!     ' Can we attack the npc?
    If CanPlayerAttackPlayer(attacker, victim) Then

        mapNum = GetPlayerMap(attacker)

        ' check if NPC can avoid the attack
        If CanPlayerDodge(victim) Then
            SendActionMsg mapNum, "Dodge!", Pink, 1, (GetPlayerX(victim) * 32), (GetPlayerY(victim) * 32)
            Exit Sub
        End If
        If CanPlayerParry(victim) Then
            SendActionMsg mapNum, "Parry!", Pink, 1, (GetPlayerX(victim) * 32), (GetPlayerY(victim) * 32)
            Exit Sub
        End If
>!         ' Get the damage we can do
        Damage = GetPlayerDamage(attacker)

        ' if the npc blocks, take away the block amount
        blockAmount = CanPlayerBlock(victim)
        Damage = Damage - blockAmount

        ' take away armour
        Damage = Damage - RAND(1, (GetPlayerStat(victim, Agility) * 2))

        ' randomise for up to 10% lower than max hit
        Damage = RAND(1, Damage)

        ' * 1.5 if can crit
        If CanPlayerCrit(attacker) Then
            Damage = Damage * 1.5
            SendActionMsg mapNum, "Critical!", BrightCyan, 1, (GetPlayerX(attacker) * 32), (GetPlayerY(attacker) * 32)
        End If
>!         If Damage > 0 Then
            Call PlayerAttackPlayer(attacker, victim, Damage)
        Else
            Call PlayerMsg(attacker, "Your attack does nothing.", BrightRed)
        End If
    End If
End Sub
>! Function CanPlayerAttackPlayer(ByVal attacker As Long, ByVal victim As Long, Optional ByVal IsSpell As Boolean = False) As Boolean
>!     If Not IsSpell Then
        ' Check attack timer
        If GetPlayerEquipment(attacker, Weapon) > 0 Then
            If GetTickCount < TempPlayer(attacker).AttackTimer + Item(GetPlayerEquipment(attacker, Weapon)).Speed Then Exit Function
        Else
            If GetTickCount < TempPlayer(attacker).AttackTimer + 1000 Then Exit Function
        End If
    End If
>!     ' Check for subscript out of range
    If Not IsPlaying(victim) Then Exit Function
>!     ' Make sure they are on the same map
    If Not GetPlayerMap(attacker) = GetPlayerMap(victim) Then Exit Function
>!     ' Make sure we dont attack the player if they are switching maps
    If TempPlayer(victim).GettingMap = YES Then Exit Function
>!     If Not IsSpell Then
        ' Check if at same coordinates
        Select Case GetPlayerDir(attacker)
            Case DIR_UP

                If Not ((GetPlayerY(victim) + 1 = GetPlayerY(attacker)) And (GetPlayerX(victim) = GetPlayerX(attacker))) Then Exit Function
            Case DIR_DOWN

                If Not ((GetPlayerY(victim) - 1 = GetPlayerY(attacker)) And (GetPlayerX(victim) = GetPlayerX(attacker))) Then Exit Function
            Case DIR_LEFT

                If Not ((GetPlayerY(victim) = GetPlayerY(attacker)) And (GetPlayerX(victim) + 1 = GetPlayerX(attacker))) Then Exit Function
            Case DIR_RIGHT

                If Not ((GetPlayerY(victim) = GetPlayerY(attacker)) And (GetPlayerX(victim) - 1 = GetPlayerX(attacker))) Then Exit Function
            Case Else
                Exit Function
        End Select
    End If
>!     ' Check if map is attackable
    If Not Map(GetPlayerMap(attacker)).Moral = MAP_MORAL_NONE Then
        If GetPlayerPK(victim) = NO Then
            Call PlayerMsg(attacker, "This is a safe zone!", BrightRed)
            Exit Function
        End If
    End If
>!     ' Make sure they have more then 0 hp
    If GetPlayerVital(victim, Vitals.HP) <= 0 Then Exit Function
>!     ' Check to make sure that they dont have access
    If GetPlayerAccess(attacker) > ADMIN_MONITOR Then
        Call PlayerMsg(attacker, "Admins cannot attack other players.", BrightBlue)
        Exit Function
    End If
>!     ' Check to make sure the victim isn't an admin
    If GetPlayerAccess(victim) > ADMIN_MONITOR Then
        Call PlayerMsg(attacker, "You cannot attack " & GetPlayerName(victim) & "!", BrightRed)
        Exit Function
    End If
>!     ' Make sure attacker is high enough level
    If GetPlayerLevel(attacker) < 10 Then
        Call PlayerMsg(attacker, "You are below level 10, you cannot attack another player yet!", BrightRed)
        Exit Function
    End If
>!     ' Make sure victim is high enough level
    If GetPlayerLevel(victim) < 10 Then
        Call PlayerMsg(attacker, GetPlayerName(victim) & " is below level 10, you cannot attack this player yet!", BrightRed)
        Exit Function
    End If
>!     CanPlayerAttackPlayer = True
End Function
>! Sub PlayerAttackPlayer(ByVal attacker As Long, ByVal victim As Long, ByVal Damage As Long, Optional ByVal spellnum As Long = 0)
    Dim exp As Long
    Dim n As Long
    Dim i As Long
    Dim Buffer As clsBuffer
>!     ' Check for subscript out of range
    If IsPlaying(attacker) = False Or IsPlaying(victim) = False Or Damage < 0 Then
        Exit Sub
    End If
>!     ' Check for weapon
    n = 0
>!     If GetPlayerEquipment(attacker, Weapon) > 0 Then
        n = GetPlayerEquipment(attacker, Weapon)
    End If

    ' set the regen timer
    TempPlayer(attacker).stopRegen = True
    TempPlayer(attacker).stopRegenTimer = GetTickCount
>!     If Damage >= GetPlayerVital(victim, Vitals.HP) Then
        SendActionMsg GetPlayerMap(victim), "-" & GetPlayerVital(victim, Vitals.HP), BrightRed, 1, (GetPlayerX(victim) * 32), (GetPlayerY(victim) * 32)

        ' send the sound
        If spellnum > 0 Then SendMapSound victim, GetPlayerX(victim), GetPlayerY(victim), SoundEntity.seSpell, spellnum

        ' Player is dead
        Call GlobalMsg(GetPlayerName(victim) & " has been killed by " & GetPlayerName(attacker), BrightRed)
        ' Calculate exp to give attacker
        exp = (GetPlayerExp(victim) \ 10)
>!         ' Make sure we dont get less then 0
        If exp < 0 Then
            exp = 0
        End If
>!         If exp = 0 Then
            Call PlayerMsg(victim, "You lost no exp.", BrightRed)
            Call PlayerMsg(attacker, "You received no exp.", BrightBlue)
        Else
            Call SetPlayerExp(victim, GetPlayerExp(victim) - exp)
            SendEXP victim
            Call PlayerMsg(victim, "You lost " & exp & " exp.", BrightRed)

            ' check if we're in a party
            If TempPlayer(attacker).inParty > 0 Then
                ' pass through party exp share function
                Party_ShareExp TempPlayer(attacker).inParty, exp, attacker
            Else
                ' not in party, get exp for self
                GivePlayerEXP attacker, exp
            End If
        End If

        ' purge target info of anyone who targetted dead guy
        For i = 1 To Player_HighIndex
            If IsPlaying(i) And IsConnected(i) Then
                If Player(i).Map = GetPlayerMap(attacker) Then
                    If TempPlayer(i).target = TARGET_TYPE_PLAYER Then
                        If TempPlayer(i).target = victim Then
                            TempPlayer(i).target = 0
                            TempPlayer(i).targetType = TARGET_TYPE_NONE
                            SendTarget i
                        End If
                    End If
                End If
            End If
        Next
>!         If GetPlayerPK(victim) = NO Then
            If GetPlayerPK(attacker) = NO Then
                Call SetPlayerPK(attacker, YES)
                Call SendPlayerData(attacker)
                Call GlobalMsg(GetPlayerName(attacker) & " has been deemed a Player Killer!!!", BrightRed)
            End If
>!         Else
            Call GlobalMsg(GetPlayerName(victim) & " has paid the price for being a Player Killer!!!", BrightRed)
        End If
Call CheckTasks(attacker, QUEST_TYPE_GOKILL, victim)
        Call OnDeath(victim)
    Else
        ' Player not dead, just do the damage
        Call SetPlayerVital(victim, Vitals.HP, GetPlayerVital(victim, Vitals.HP) - Damage)
        Call SendVital(victim, Vitals.HP)

        ' send vitals to party if in one
        If TempPlayer(victim).inParty > 0 Then SendPartyVitals TempPlayer(victim).inParty, victim

        ' send the sound
        If spellnum > 0 Then SendMapSound victim, GetPlayerX(victim), GetPlayerY(victim), SoundEntity.seSpell, spellnum

        SendActionMsg GetPlayerMap(victim), "-" & Damage, BrightRed, 1, (GetPlayerX(victim) * 32), (GetPlayerY(victim) * 32)
        SendBlood GetPlayerMap(victim), GetPlayerX(victim), GetPlayerY(victim)

        ' set the regen timer
        TempPlayer(victim).stopRegen = True
        TempPlayer(victim).stopRegenTimer = GetTickCount

        'if a stunning spell, stun the player
        If spellnum > 0 Then
            If Spell(spellnum).StunDuration > 0 Then StunPlayer victim, spellnum
            ' DoT
            If Spell(spellnum).Duration > 0 Then
                AddDoT_Player victim, spellnum, attacker
            End If
        End If
    End If
>!     ' Reset attack timer
    TempPlayer(attacker).AttackTimer = GetTickCount
End Sub
>! ' ############
' ## Spells ##
' ############
>! Public Sub BufferSpell(ByVal Index As Long, ByVal spellslot As Long)
    Dim spellnum As Long
    Dim MPCost As Long
    Dim LevelReq As Long
    Dim mapNum As Long
    Dim SpellCastType As Long
    Dim ClassReq As Long
    Dim AccessReq As Long
    Dim Range As Long
    Dim HasBuffered As Boolean

    Dim targetType As Byte
    Dim target As Long

    ' Prevent subscript out of range
    If spellslot <= 0 Or spellslot > MAX_PLAYER_SPELLS Then Exit Sub

    spellnum = GetPlayerSpell(Index, spellslot)
    mapNum = GetPlayerMap(Index)

    If spellnum <= 0 Or spellnum > MAX_SPELLS Then Exit Sub

    ' Make sure player has the spell
    If Not HasSpell(Index, spellnum) Then Exit Sub

    ' see if cooldown has finished
    If TempPlayer(Index).SpellCD(spellslot) > GetTickCount Then
        PlayerMsg Index, "Spell hasn't cooled down yet!", BrightRed
        Exit Sub
    End If
>!     MPCost = Spell(spellnum).MPCost
>!     ' Check if they have enough MP
    If GetPlayerVital(Index, Vitals.MP) < MPCost Then
        Call PlayerMsg(Index, "Not enough mana!", BrightRed)
        Exit Sub
    End If

    LevelReq = Spell(spellnum).LevelReq
>!     ' Make sure they are the right level
    If LevelReq > GetPlayerLevel(Index) Then
        Call PlayerMsg(Index, "You must be level " & LevelReq & " to cast this spell.", BrightRed)
        Exit Sub
    End If

    AccessReq = Spell(spellnum).AccessReq

    ' make sure they have the right access
    If AccessReq > GetPlayerAccess(Index) Then
        Call PlayerMsg(Index, "You must be an administrator to cast this spell.", BrightRed)
        Exit Sub
    End If

    ClassReq = Spell(spellnum).ClassReq

    ' make sure the classreq > 0
    If ClassReq > 0 Then ' 0 = no req
        If ClassReq <> GetPlayerClass(Index) Then
            Call PlayerMsg(Index, "Only " & CheckGrammar(Trim$(Class(ClassReq).Name)) & " can use this spell.", BrightRed)
            Exit Sub
        End If
    End If

    ' find out what kind of spell it is! self cast, target or AOE
    If Spell(spellnum).Range > 0 Then
        ' ranged attack, single target or aoe?
        If Not Spell(spellnum).IsAoE Then
            SpellCastType = 2 ' targetted
        Else
            SpellCastType = 3 ' targetted aoe
        End If
    Else
        If Not Spell(spellnum).IsAoE Then
            SpellCastType = 0 ' self-cast
        Else
            SpellCastType = 1 ' self-cast AoE
        End If
    End If

    targetType = TempPlayer(Index).targetType
    target = TempPlayer(Index).target
    Range = Spell(spellnum).Range
    HasBuffered = False

    Select Case SpellCastType
        Case 0, 1 ' self-cast & self-cast AOE
            HasBuffered = True
        Case 2, 3 ' targeted & targeted AOE
            ' check if have target
            If Not target > 0 Then
                PlayerMsg Index, "You do not have a target.", BrightRed
            End If
            If targetType = TARGET_TYPE_PLAYER Then
                ' if have target, check in range
                If Not isInRange(Range, GetPlayerX(Index), GetPlayerY(Index), GetPlayerX(target), GetPlayerY(target)) Then
                    PlayerMsg Index, "Target not in range.", BrightRed
                El
```
Link to comment
Share on other sites

rather annoying bug
system lets a 'task' finish with out requierments being met.
example
go cut wood
"give item 6 (wood) to npc 1 amount 2" if i just talk to the npc it acts as if the task was done
current work around. make item needed to START quest ( empty quest)  but then i can only require one item
Link to comment
Share on other sites

@Psiwold:

> it tells me "Compile error:  Method or data member not found"  Then it highlights
> .Quest

In **modTypes**: find "**Private Type NpcRec**" and at the bottom before 'End Type' Make sure you add:
```
Quest As Byte
    QuestNum As Long
```
Link to comment
Share on other sites

> **How it Works**
> Temporary, it's working this way, but you could add buttons if you wish, and edit the ugly GUI forms and stuff. To open the Quest Editor type /editquest, to open the QuestLog press the white button.

First page of the tutorial is what I meant sorry for any confusion
http://www.touchofdeathforums.com/smf/index.php/topic,70502.0.html
Link to comment
Share on other sites

I was seeing here an error, not to solve it, but when I try to power, I am very busy, the error is as follows, when we finish a quest to pick up items X and start it again it already has said it already has all the items. example:

Here is the message (do not remember the message) and after have the following: "10/10", so this is an example might be more ally the amount of item to be searched. thank you
Link to comment
Share on other sites

@Ryoku:

> still in class got on their network with my laptop.
>
> FIX EXP:
>
> Server side
>
> in modSvQuests find 'give experience
> replace the line under it with
> ```
> 'give experience
>    
>     GivePlayerEXP Index, Quest(QuestNum).RewardExp
>    
>
> ```
>
> * * *
>
> ! or ? mark above quest NPCs:
>
> Client Side
>
> in modText
>
> In Public Sub DrawNpcName
>
> before ' Error handler
>
> add
> ```
>     If NPC(NPCNum).Quest = YES Then
>         Name = "?" 'or !
>    
>         TextX = ConvertMapX(MapNpc(Index).x * PIC_X) + MapNpc(Index).XOffset + (PIC_X \ 2) - getWidth(TexthDC, (Trim$(Name)))
>         If NPC(NPCNum).Sprite < 1 Or NPC(NPCNum).Sprite > NumCharacters Then
>             TextY = ConvertMapY(MapNpc(Index).y * PIC_Y) + MapNpc(Index).YOffset - 16
>         Else
>             ' Determine location for text
>             TextY = ConvertMapY(MapNpc(Index).y * PIC_Y) + MapNpc(Index).YOffset - (DDSD_Character(NPC(NPCNum).Sprite).lHeight / 4) + 4 'adjust last number to get it to fit right
>         End If
>         ' Draw name
>         Call DrawText(TexthDC, TextX, TextY, Name, color)
>     End If
>    
>
> ```

The ? or ! above NPC's heads wouldn't work for me.
Link to comment
Share on other sites

Hello i'm a very beginner in vb6 and i cant' fix the questlog problem. I create the button and put the code in there and that works. But i can't go into other menus like options,spells,etc after clicking on the quest button's.

Is anyone can give me the right code i have to add in the loquest button on vb6? Thanks a lot a sorry for my bad english :s

thx!

**Edit:** Omg i found myself! I try something and i works! I just add "picQuestLog.Visible = False" on the others Case and it works great.

It's maybe nothing for you guys but it's a big step for me!

Well thx me :) And thx Alastar for this great Quest system!
Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
 Share


×
×
  • Create New...