[EO] Buff/DeBuff Spells V1.2

Yes there already is a Buffs tutorial but this one is better.

In this mod you will get:

  • 18 Types of Buffs/Debuffs
  • The ability to have 10 Buffs active on a player at once (including multiples of the same buff)
  • Buffs with stackable effects
  • Casting and Cooldown times
  • Animations
  • Less buggy code
  • Buffs that can be limited to casting only on yourself
  • buffs that can be cast on anyone
  • Longer buff timers based on Will stat
    -Cant hit players with debuffs while in safe zones

All credits for this Buff system belong to Ryoku Hasu.

How to use:

-Setting the spell Vital will set the value of the Buff

-Setting it to self-cast will make it so you can only cast it on yourself

-Set the Duration of the spell to set the Base amount of time the buff will last

-And  buff will last longer the higher your Will stat is

-Stats DO NOT affect the amount the buff changes, only the time it lasts.

Pre-Required Tuts: Adding Real Defense
http://www.touchofdeathforums.com/smf/index.php/topic,73579.0.html

CLIENT AND SERVER

In modConstants

under

’ Spell constants

add at the bottom

Public Const SPELL_TYPE_BUFF As Byte = 5 ' or next number in your list

and bellow that add

'Buff Types
Public Const BUFF_NONE As Byte = 0
Public Const BUFF_ADD_HP As Byte = 1
Public Const BUFF_ADD_MP As Byte = 2
Public Const BUFF_ADD_STR As Byte = 3
Public Const BUFF_ADD_END As Byte = 4
Public Const BUFF_ADD_AGI As Byte = 5
Public Const BUFF_ADD_INT As Byte = 6
Public Const BUFF_ADD_WILL As Byte = 7
Public Const BUFF_ADD_ATK As Byte = 8
Public Const BUFF_ADD_DEF As Byte = 9
Public Const BUFF_SUB_HP As Byte = 10
Public Const BUFF_SUB_MP As Byte = 11
Public Const BUFF_SUB_STR As Byte = 12
Public Const BUFF_SUB_END As Byte = 13
Public Const BUFF_SUB_AGI As Byte = 14
Public Const BUFF_SUB_INT As Byte = 15
Public Const BUFF_SUB_WILL As Byte = 16
Public Const BUFF_SUB_ATK As Byte = 17
Public Const BUFF_SUB_DEF As Byte = 18

In modTypes

in Private Type SpellRec add at the bottom

BuffType As Long

SERVER SIDE

In modTypes

In Public Type TempPlayerRec
add to the bottom


    Buffs(1 To 10) As Long
    BuffTimer(1 To 10) As Long
    BuffValue(1 To 10) As Long

In modServerLoop

In Sub ServerLoop()

at the top add

Dim BuffTimer As Long

above

' Check for disconnections every half second

add

If Tick > BuffTimer Then
            For I = 1 To Player_HighIndex
                For x = 1 To 10
                    If TempPlayer(I).BuffTimer(x) > 0 Then
                        TempPlayer(I).BuffTimer(x) = TempPlayer(I).BuffTimer(x) - 1
                        If TempPlayer(I).BuffTimer(x) = 0 Then
                            TempPlayer(I).Buffs(x) = 0
                        End If
                    End If
                Next
            Next
            BuffTimer = GetTickCount + 1000
        End If

In modPlayer

Replace Public Function GetPlayerStat with

Public Function GetPlayerStat(ByVal Index As Long, ByVal stat As Stats) As Long
    Dim x As Long, I As Long
    If Index > MAX_PLAYERS Then Exit Function

    x = Player(Index).stat(stat)

    For I = 1 To Equipment.Equipment_Count - 1
        If Player(Index).Equipment(I) > 0 Then
            If Item(Player(Index).Equipment(I)).Add_Stat(stat) > 0 Then
                x = x + Item(Player(Index).Equipment(I)).Add_Stat(stat)
            End If
        End If
    Next

    Select Case stat
        Case Stats.Strength
            For I = 1 To 10
                If TempPlayer(Index).Buffs(I) = BUFF_ADD_STR Then
                    x = x + TempPlayer(Index).BuffValue(I)
                End If
                If TempPlayer(Index).Buffs(I) = BUFF_SUB_STR Then
                    x = x - TempPlayer(Index).BuffValue(I)
                End If
            Next
        Case Stats.Endurance
            For I = 1 To 10
                If TempPlayer(Index).Buffs(I) = BUFF_ADD_END Then
                    x = x + TempPlayer(Index).BuffValue(I)
                End If
                If TempPlayer(Index).Buffs(I) = BUFF_SUB_END Then
                    x = x - TempPlayer(Index).BuffValue(I)
                End If
            Next
        Case Stats.Agility
            For I = 1 To 10
                If TempPlayer(Index).Buffs(I) = BUFF_ADD_AGI Then
                    x = x + TempPlayer(Index).BuffValue(I)
                End If
                If TempPlayer(Index).Buffs(I) = BUFF_SUB_AGI Then
                    x = x - TempPlayer(Index).BuffValue(I)
                End If
            Next
        Case Stats.Intelligence
            For I = 1 To 10
                If TempPlayer(Index).Buffs(I) = BUFF_ADD_INT Then
                    x = x + TempPlayer(Index).BuffValue(I)
                End If
                If TempPlayer(Index).Buffs(I) = BUFF_SUB_INT Then
                    x = x - TempPlayer(Index).BuffValue(I)
                End If
            Next
        Case Stats.Willpower
            For I = 1 To 10
                If TempPlayer(Index).Buffs(I) = BUFF_ADD_WILL Then
                    x = x + TempPlayer(Index).BuffValue(I)
                End If
                If TempPlayer(Index).Buffs(I) = BUFF_SUB_WILL Then
                    x = x - TempPlayer(Index).BuffValue(I)
                End If
            Next
    End Select

    GetPlayerStat = x
End Function

And at the bottom of modPlayer add

Public Sub ApplyBuff(ByVal Index As Long, ByVal BuffType As Long, ByVal Duration As Long, ByVal Amount As Long)
    Dim I As Long

    For I = 1 To 10
        If TempPlayer(Index).Buffs(I) = 0 Then
            TempPlayer(Index).Buffs(I) = BuffType
            TempPlayer(Index).BuffTimer(I) = Duration
            TempPlayer(Index).BuffValue(I) = Amount
            Exit For
        End If
    Next

    If BuffType = BUFF_ADD_HP Then
        Call SetPlayerVital(Index, HP, GetPlayerVital(Index, Vitals.HP) + Amount)
    End If
    If BuffType = BUFF_ADD_MP Then
        Call SetPlayerVital(Index, MP, GetPlayerVital(Index, Vitals.MP) + Amount)
    End If

    For I = 1 To Vitals.Vital_Count - 1
        Call SendVital(Index, I)
    Next

End Sub

In modCombat

In Function GetPlayerMaxVital (right at to top)

At the top add

Dim I As Long

Just above “Case MP” add

            For I = 1 To 10
                If TempPlayer(Index).Buffs(I) = BUFF_ADD_HP Then
                    GetPlayerMaxVital = GetPlayerMaxVital + TempPlayer(Index).BuffValue(I)

                End If
                If TempPlayer(Index).Buffs(I) = BUFF_SUB_HP Then
                    GetPlayerMaxVital = GetPlayerMaxVital - TempPlayer(Index).BuffValue(I)
                End If
            Next

and just before the LAST “End Select” in GetPlayerMaxVital add

For I = 1 To 10
                If TempPlayer(Index).Buffs(I) = BUFF_ADD_MP Then
                    GetPlayerMaxVital = GetPlayerMaxVital + TempPlayer(Index).BuffValue(I)
                End If
                If TempPlayer(Index).Buffs(I) = BUFF_SUB_MP Then
                    GetPlayerMaxVital = GetPlayerMaxVital - TempPlayer(Index).BuffValue(I)
                End If
            Next

in Function GetPlayerDamage

At the top add

Dim I As Long

at the bottom add

For I = 1 To 10
        If TempPlayer(Index).Buffs(I) = BUFF_ADD_ATK Then
            GetPlayerDamage = GetPlayerDamage + TempPlayer(Index).BuffValue(I)
        End If
        If TempPlayer(Index).Buffs(I) = BUFF_SUB_ATK Then
            GetPlayerDamage = GetPlayerDamage - TempPlayer(Index).BuffValue(I)
        End If
    Next

in Function GetPlayerDef
at the top add

Dim I As Long

add at the bottom

For I = 1 To 10
        If TempPlayer(Index).Buffs(I) = BUFF_ADD_DEF Then
            GetPlayerDef = GetPlayerDef + TempPlayer(Index).BuffValue(I)
        End If
        If TempPlayer(Index).Buffs(I) = BUFF_SUB_DEF Then
            GetPlayerDef = GetPlayerDef - TempPlayer(Index).BuffValue(I)
        End If
    Next

in Public Sub CastSpell

At the top add

Dim Dur As Long

from

' set the vital

to just above

AoE = Spell(spellnum).AoE

replace with (Assuming you used my Spell scaling formula tutorial, if not you will have to change the right lines back to what you want)

If Spell(spellnum).Type <> SPELL_TYPE_BUFF Then
        Vital = Spell(spellnum).Vital
        Vital = Round((Vital * 0.6)) * Round((Player(Index).Level * 1.14)) * Round((Stats.Intelligence + (Stats.Willpower / 2)))

        If Spell(spellnum).Type = SPELL_TYPE_HEALHP Then
            Vital = Vital + Round((GetPlayerStat(Index, Stats.Willpower) * 1.2))
        End If

        If Spell(spellnum).Type = SPELL_TYPE_DAMAGEHP Then
            Vital = Vital + Round((GetPlayerStat(Index, Stats.Intelligence) * 1.2))
        End If
    End If

    If Spell(spellnum).Type = SPELL_TYPE_BUFF Then
        If Round(GetPlayerStat(Index, Stats.Willpower) / 5) > 1 Then
            Dur = Spell(spellnum).Duration * Round(GetPlayerStat(Index, Stats.Willpower) / 5)
        Else
            Dur = Spell(spellnum).Duration
        End If
    End If

under

Case 0 ' self-cast target
            Select Case Spell(spellnum).Type

add

                Case SPELL_TYPE_BUFF  
                        Call ApplyBuff(Index, Spell(spellnum).BuffType, Dur, Spell(spellnum).Vital)
                        SendAnimation GetPlayerMap(Index), Spell(spellnum).SpellAnim, 0, 0, TARGET_TYPE_PLAYER, Index
                        ' send the sound
                        SendMapSound Index, GetPlayerX(Index), GetPlayerY(Index), SoundEntity.seSpell, spellnum
                        DidCast = True

above Both the “End Select” at the bottom add

Case SPELL_TYPE_BUFF
                    If targetType = TARGET_TYPE_PLAYER Then
                        If Spell(spellnum).BuffType <= BUFF_ADD_DEF And Map(GetPlayerMap(Index)).Moral <> MAP_MORAL_NONE Or Spell(spellnum).BuffType > BUFF_NONE And Map(GetPlayerMap(Index)).Moral = MAP_MORAL_NONE Then
                            Call ApplyBuff(target, Spell(spellnum).BuffType, Dur, Spell(spellnum).Vital)
                            SendAnimation GetPlayerMap(Index), Spell(spellnum).SpellAnim, 0, 0, TARGET_TYPE_PLAYER, target
                            ' send the sound
                            SendMapSound Index, GetPlayerX(Index), GetPlayerY(Index), SoundEntity.seSpell, spellnum
                            DidCast = True
                        Else
                            PlayerMsg Index, "You can not debuff another player in a safe zone!", BrightRed
                        End If
                    End If

CLIENT SIDE

On frmEditor_Spell Make a ComboBox and name it “cmbBuffType”

For ComboBox in Properties > List (lower right of VB6)
fill out the list in the following order

NONE

  • HP
  • MP
  • STR
  • END
  • AGI
  • INT
  • WILL
  • ATK
  • Def
  • HP
  • MP
  • STR
  • END
  • AGI
  • INT
  • WILL
  • ATK
  • DEF

2xClick cmbBuffType and Replace the given default with

Private Sub cmbBuffType_Click()
    Spell(EditorIndex).BuffType = cmbBuffType.ListIndex
End Sub

Click on cmbType and in Properties > List add " Buff/DeBeff" to the bottom

In modGameEditors

In Public Sub SpellEditorInit()

above

' find the sound we have set

add

.cmbBuffType.ListIndex = Spell(EditorIndex).BuffType

DONE

This is awesome looking… Does it work with your real defense and block fix?

Yes it does!

Does this also has icons so you can see which buffs are active?

This post is deleted!

@Erwin:

Does this also has icons so you can see which buffs are active?

Nope

@Captain:

Code could be optimized a lot more. This has a LOT of loops which will slow down the server a fuckton.

            For I = 1 To Player_HighIndex
                For x = 1 To 10

```What if you have 200~ players online?

Its no worse the the “For x = 1 To MAX_DOTS” loop nested in the other “For I = 1 To Player_HighIndex”  loop  just above.  And so maybe it can be optimized a bit, but so could lots of things about the Default EO.

When unlocked you CSP is well over 500,000 you won’t miss a few thousand extra because you have a ton of players being checked for buffs.

Edit: Found and Fixed an Error in the self cast buffs.

@Ryoku:

Nope

Its no worse the the “For x = 1 To MAX_DOTS” loop nested in the other “For I = 1 To Player_HighIndex”  loop  just above.  And so maybe it can be optimized a bit, but so could lots of things about the Default EO.

When unlocked you CSP is well over 500,000 you wont miss a few thousand.
Edit: Found and Fixed an Error in the self cast buffs.

Try that with 200 people in-game. Most of origins code is poorly done and optimized, Robin admits this. Does that mean you have to match that? No.

Ok then How would you store and Check 10 Stackable and simultaneous Buff Timer values?

@Ryoku:

Ok then How would you store and Check 10 Stackable and simultaneous Buff Timer values?

You wouldn’t.

I was asking for purposes of improving the code, but if your going to be like that, GTFO.

@Ryoku:

I was asking for purposes of improving the code, but if your going to be like that, GTFO.

Captain Wabbit might be saying that you don’t have to store the data or use that timer. Maybe he meant that there’s a alternate method.

He could also just be posting to annoy you.

ANYWAY…. Found a slight error with animation for casting on others, Fixed it.

@Ryoku:

I was asking for purposes of improving the code, but if your going to be like that, GTFO.

You look at this whole programming thing very closed-minded and 1 sided. You need to think outside of the “EO standard” you’re so used to.

Well you could have given a bit more explanation to your answer. I code what I think of and that is about it, I don’t sit there and ask myself “Could I make this a different and better way.” That’s why I asked you.

Now let me ask again, how would you go about it?

Works very good 😄

Looks like a decent system. I’ll be adding this for sure.

I’m getting an error in the server>modCombat>Function getmaxplayervital

Error: Variable not defined.
BUFF_ADD_HP

@nexusrightsi:

I’m getting an error in the server>modCombat>Function getmaxplayervital

Error: Variable not defined.
BUFF_ADD_HP

'Buff Types
Public Const BUFF_NONE As Byte = 0
Public Const BUFF_ADD_HP As Byte = 1
Public Const BUFF_ADD_MP As Byte = 2
Public Const BUFF_ADD_STR As Byte = 3
Public Const BUFF_ADD_END As Byte = 4
Public Const BUFF_ADD_AGI As Byte = 5
Public Const BUFF_ADD_INT As Byte = 6
Public Const BUFF_ADD_WILL As Byte = 7
Public Const BUFF_ADD_ATK As Byte = 8
Public Const BUFF_ADD_DEF As Byte = 9
Public Const BUFF_SUB_HP As Byte = 10
Public Const BUFF_SUB_MP As Byte = 11
Public Const BUFF_SUB_STR As Byte = 12
Public Const BUFF_SUB_END As Byte = 13
Public Const BUFF_SUB_AGI As Byte = 14
Public Const BUFF_SUB_INT As Byte = 15
Public Const BUFF_SUB_WILL As Byte = 16
Public Const BUFF_SUB_ATK As Byte = 17
Public Const BUFF_SUB_DEF As Byte = 18

```add these to modConstants

Thank you so much Cpt Wabbit =3, and thank you for this buff/debuff system ^^

EDIT:

error: run-time error "9" subscript out of range

Client>modHandleData>Private Sub HandleUpdateSpell

CopyMemory ByVal VarPtr(Spell(spellnum)), ByVal VarPtr(SpellData(0)), SpellSize

If I wanted to just have 5 buffs active at a time do I just change the '10’s to 5’s?

Log in to reply