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

[EO 2.0] Punching/Kicking


Gohan
 Share

Recommended Posts

This is my first tutorial, go easy on me  :P

**Note: This feature uses da_gad_pader's [[EO 2.0]'How to make an attack animation/frame'](http://www.touchofdeathforums.com/smf/index.php/topic,72272.0.html) so other players will be unable to see you punching/kicking, until the issue on that tutorial gets fixed.**

Client:

In modGameLogic
Replace Public Sub CheckAttack with 2 subs

```
Public Sub CheckAttack1()
Dim Buffer As clsBuffer
Dim attackspeed As Long

    ' If debug mode, handle error then exit out
    If Options.Debug = 1 Then On Error GoTo errorhandler

    If GetKeyState(vbKeyP) < 0 Then

        If SpellBuffer > 0 Then Exit Sub ' currently casting a spell, can't attack
        If StunDuration > 0 Then Exit Sub ' stunned, can't attack

        ' speed from weapon
        If GetPlayerEquipment(MyIndex, Weapon) > 0 Then
            attackspeed = Item(GetPlayerEquipment(MyIndex, Weapon)).Speed
        Else
            attackspeed = 1000
        End If

        If Player(MyIndex).AttackTimer + attackspeed < GetTickCount Then
            If Player(MyIndex).Attacking1 = 0 Then

                With Player(MyIndex)
                    .Attacking1 = 1
                    .AttackTimer = GetTickCount
                End With

                Set Buffer = New clsBuffer
                Buffer.WriteLong CAttack1
                SendData Buffer.ToArray()
                Set Buffer = Nothing
            End If
        End If
    End If

    ' Error handler
    Exit Sub
errorhandler:
    HandleError "CheckAttack1", "modGameLogic", Err.Number, Err.Description, Err.Source, Err.HelpContext
    Err.Clear
    Exit Sub
End Sub
```
```
Public Sub CheckAttack2()
Dim Buffer As clsBuffer
Dim attackspeed As Long

    ' If debug mode, handle error then exit out
    If Options.Debug = 1 Then On Error GoTo errorhandler

    If GetKeyState(vbKeyO) < 0 Then

        If SpellBuffer > 0 Then Exit Sub ' currently casting a spell, can't attack
        If StunDuration > 0 Then Exit Sub ' stunned, can't attack

        ' speed from weapon
        If GetPlayerEquipment(MyIndex, Weapon) > 0 Then
            attackspeed = Item(GetPlayerEquipment(MyIndex, Weapon)).Speed
        Else
            attackspeed = 1000
        End If

        If Player(MyIndex).AttackTimer + attackspeed < GetTickCount Then
            If Player(MyIndex).Attacking2 = 0 Then

                With Player(MyIndex)
                    .Attacking2 = 1
                    .AttackTimer = GetTickCount
                End With

                Set Buffer = New clsBuffer
                Buffer.WriteLong CAttack2
                SendData Buffer.ToArray()
                Set Buffer = Nothing
            End If
        End If
    End If

    ' Error handler
    Exit Sub
errorhandler:
    HandleError "CheckAttack2", "modGameLogic", Err.Number, Err.Description, Err.Source, Err.HelpContext
    Err.Clear
    Exit Sub
End Sub
```
And in GameLoop
```
Call CheckAttack  ' Check to see if player is trying to attack
```
To

```
Call CheckAttack1  ' Check to see if player is trying to attack
                Call CheckAttack2  ' Check to see if player is trying to attack
```

In ModTypes Private Type PlayerRec

```
Attacking As Byte
```
To

```
Attacking1 As Byte
Attacking2 As Byte
```
In ModTypes Private Type MapNpcRec

```
Attacking As Byte
```
To

```
Attacking1 As Byte
Attacking2 As Byte
```
In ModDirectDraw7 BltPlayer

Add```
Dim AtkTimer As Long
```At the top

```
' Check for attacking animation
    If Player(Index).AttackTimer + (attackspeed / 2) > GetTickCount Then
        If Player(Index).Attacking = 1 Then
              Anim = 4
        End If
```To

```
        ' Check for attacking animation
    If Player(Index).AttackTimer + (attackspeed / 2) > GetTickCount Then
        If Player(Index).Attacking1 = 1 Then
        AtkTimer = (GetTickCount - Player(Index).AttackTimer)
            If AtkTimer < 250 Then
            Anim = 4
            End If
                If AtkTimer < 500 And AtkTimer >= 250 Then ' Add or remove with same pattern to change frame number
                Anim = 5
                End If
                    If AtkTimer < 750 And AtkTimer >= 500 Then ' Add or remove with same pattern to change frame number
                    Anim = 6
                    End If
                        If AtkTimer < 1000 And AtkTimer >= 750 Then ' Add or remove with same pattern to change frame number
                        Anim = 7
                        End If
                            If AtkTimer >= 1000 Then
                            Anim = 0
                            End If
        End If
        If Player(Index).Attacking2 = 1 Then
        AtkTimer = (GetTickCount - Player(Index).AttackTimer)
            If AtkTimer < 250 Then
            Anim = 8
            End If
                If AtkTimer < 500 And AtkTimer >= 250 Then ' Add or remove with same pattern to change frame number
                Anim = 9
                End If
                    If AtkTimer < 750 And AtkTimer >= 500 Then ' Add or remove with same pattern to change frame number
                    Anim = 10
                    End If
                        If AtkTimer < 1000 And AtkTimer >= 750 Then ' Add or remove with same pattern to change frame number
                        Anim = 11
                        End If
                            If AtkTimer >= 1000 Then
                            Anim = 0
                            End If

        End If
```
And

```
    With Player(Index)
        If .AttackTimer + attackspeed < GetTickCount Then
            .Attacking = 0
            .AttackTimer = 0
        End If
    End With
```
To

```
    With Player(Index)
        If .AttackTimer + attackspeed < GetTickCount Then
            .Attacking1 = 0
            .Attacking2 = 0
            .AttackTimer = 0
        End If
    End With
```
And

```
    With rec
        .top = spritetop * (DDSD_Character(Sprite).lHeight / 4)
        .Bottom = .top + (DDSD_Character(Sprite).lHeight / 4)
        .Left = Anim * (DDSD_Character(Sprite).lWidth / 4)
        .Right = .Left + (DDSD_Character(Sprite).lWidth / 4)
    End With
```
To

```
    With rec
        .top = spritetop * (DDSD_Character(Sprite).lHeight / 4)
        .Bottom = .top + (DDSD_Character(Sprite).lHeight / 4)
        .Left = Anim * (DDSD_Character(Sprite).lWidth / 12) ' Number of frames on char sheet
        .Right = .Left + (DDSD_Character(Sprite).lWidth / 12) ' Number of frames on char sheet
    End With
```
And

```
    ' Calculate the X
    x = GetPlayerX(Index) * PIC_X + Player(Index).XOffset - ((DDSD_Character(Sprite).lWidth / 4 - 32) / 2)
```
To

```
    ' Calculate the X
    x = GetPlayerX(Index) * PIC_X + Player(Index).XOffset - ((DDSD_Character(Sprite).lWidth / 4 - 96) / 2)  ' adjust sprite displacement
```
In ModDirectDraw7 BltNpc

Add```
Dim AtkTimer As Long
```At the top

```
    ' Check for attacking animation
    If MapNpc(MapNpcNum).AttackTimer + (attackspeed / 2) > GetTickCount Then
        If MapNpc(MapNpcNum).Attacking1 = 1 Then
                Anim = 4
        End If
```
To

```
        ' Check for attacking animation
    If MapNpc(MapNpcNum).AttackTimer + (attackspeed / 2) > GetTickCount Then
        If MapNpc(MapNpcNum).Attacking1 = 1 Then
        AtkTimer = (GetTickCount - MapNpc(MapNpcNum).AttackTimer)
            If AtkTimer < 250 Then
            Anim = 4
            End If
                If AtkTimer < 500 And AtkTimer >= 250 Then ' Add or remove with same pattern to change frame number
                Anim = 5
                End If
                    If AtkTimer < 750 And AtkTimer >= 500 Then ' Add or remove with same pattern to change frame number
                    Anim = 6
                    End If
                        If AtkTimer < 1000 And AtkTimer >= 750 Then ' Add or remove with same pattern to change frame number
                        Anim = 7
                        End If
                            If AtkTimer >= 1000 Then
                            Anim = 0
                            End If
        End If
        If MapNpc(MapNpcNum).Attacking2 = 1 Then
        AtkTimer = (GetTickCount - MapNpc(MapNpcNum).AttackTimer)
            If AtkTimer < 250 Then
            Anim = 8
            End If
                If AtkTimer < 500 And AtkTimer >= 250 Then ' Add or remove with same pattern to change frame number
                Anim = 9
                End If
                    If AtkTimer < 750 And AtkTimer >= 500 Then ' Add or remove with same pattern to change frame number
                    Anim = 10
                    End If
                        If AtkTimer < 1000 And AtkTimer >= 750 Then ' Add or remove with same pattern to change frame number
                        Anim = 11
                        End If
                            If AtkTimer >= 1000 Then
                            Anim = 0
                            End If

        End If
```
And

```
    ' Check to see if we want to stop making him attack
    With MapNpc(MapNpcNum)
        If .AttackTimer + attackspeed < GetTickCount Then
            .Attacking = 0
            .AttackTimer = 0
        End If
```
To

```
    With MapNpc(MapNpcNum)
        If .AttackTimer + attackspeed < GetTickCount Then
            .Attacking1 = 0
            .Attacking2 = 0
            .AttackTimer = 0
        End If
    End With
```
And

```
    With rec
        .top = spritetop * (DDSD_Character(Sprite).lHeight / 4)
        .Bottom = .top + (DDSD_Character(Sprite).lHeight / 4)
        .Left = Anim * (DDSD_Character(Sprite).lWidth / 4)
        .Right = .Left + (DDSD_Character(Sprite).lWidth / 4)
    End With
```
To

```
    With rec
        .top = spritetop * (DDSD_Character(Sprite).lHeight / 4)
        .Bottom = .top + (DDSD_Character(Sprite).lHeight / 4)
        .Left = Anim * (DDSD_Character(Sprite).lWidth / 12) ' Number of frames on char sheet
        .Right = .Left + (DDSD_Character(Sprite).lWidth / 12) ' Number of frames on char sheet
    End With
```
And

```
    ' Calculate the X
    x = MapNpc(MapNpcNum).x * PIC_X + MapNpc(MapNpcNum).XOffset - ((DDSD_Character(Sprite).lWidth / 4 - 32) / 2)
```
To

```
    ' Calculate the X
    x = MapNpc(MapNpcNum).x * PIC_X + MapNpc(MapNpcNum).XOffset - ((DDSD_Character(Sprite).lWidth / 4 - 96) / 2) ' adjust sprite displacement
```
In modHandleData change Sub HandleAttack to 2 subs
```
Private Sub HandleAttack1(ByVal Index As Long, ByRef Data() As Byte, ByVal StartAddr As Long, ByVal ExtraVar As Long)
Dim i As Long
Dim Buffer As clsBuffer

    ' If debug mode, handle error then exit out
    If Options.Debug = 1 Then On Error GoTo errorhandler

    Set Buffer = New clsBuffer
    Buffer.WriteBytes Data()
    i = Buffer.ReadLong
    ' Set player to attacking
    Player(i).Attacking1 = 1
    Player(i).AttackTimer = GetTickCount

    ' Error handler
    Exit Sub
errorhandler:
    HandleError "HandleAttack", "modHandleData", Err.Number, Err.Description, Err.Source, Err.HelpContext
    Err.Clear
    Exit Sub
End Sub
```
```
Private Sub HandleAttack2(ByVal Index As Long, ByRef Data() As Byte, ByVal StartAddr As Long, ByVal ExtraVar As Long)
Dim i As Long
Dim Buffer As clsBuffer

    ' If debug mode, handle error then exit out
    If Options.Debug = 1 Then On Error GoTo errorhandler

    Set Buffer = New clsBuffer
    Buffer.WriteBytes Data()
    i = Buffer.ReadLong
    ' Set player to attacking
    Player(i).Attacking2 = 1
    Player(i).AttackTimer = GetTickCount

    ' Error handler
    Exit Sub
errorhandler:
    HandleError "HandleAttack", "modHandleData", Err.Number, Err.Description, Err.Source, Err.HelpContext
    Err.Clear
    Exit Sub
End Sub
```
And

Sub HandleNpcAttack

To

```
Private Sub HandleNpcAttack1(ByVal Index As Long, ByRef Data() As Byte, ByVal StartAddr As Long, ByVal ExtraVar As Long)
Dim i As Long
Dim Buffer As clsBuffer

    ' If debug mode, handle error then exit out
    If Options.Debug = 1 Then On Error GoTo errorhandler

    Set Buffer = New clsBuffer
    Buffer.WriteBytes Data()
    i = Buffer.ReadLong
    ' Set player to attacking
    MapNpc(i).Attacking1 = 1
    MapNpc(i).AttackTimer = GetTickCount

    ' Error handler
    Exit Sub
errorhandler:
    HandleError "HandleNpcAttack", "modHandleData", Err.Number, Err.Description, Err.Source, Err.HelpContext
    Err.Clear
    Exit Sub
End Sub
```
```
Private Sub HandleNpcAttack2(ByVal Index As Long, ByRef Data() As Byte, ByVal StartAddr As Long, ByVal ExtraVar As Long)
Dim i As Long
Dim Buffer As clsBuffer

    ' If debug mode, handle error then exit out
    If Options.Debug = 1 Then On Error GoTo errorhandler

    Set Buffer = New clsBuffer
    Buffer.WriteBytes Data()
    i = Buffer.ReadLong
    ' Set player to attacking
    MapNpc(i).Attacking2 = 1
    MapNpc(i).AttackTimer = GetTickCount

    ' Error handler
    Exit Sub
errorhandler:
    HandleError "HandleNpcAttack", "modHandleData", Err.Number, Err.Description, Err.Source, Err.HelpContext
    Err.Clear
    Exit Sub
End Sub
```
And

```
HandleDataSub(SAttack) = GetAddress(AddressOf HandleAttack)
HandleDataSub(SNpcAttack = GetAddress(AddressOf HandleNpcAttack)
```
To

```
    HandleDataSub(SAttack1) = GetAddress(AddressOf HandleAttack1)
    HandleDataSub(SAttack2) = GetAddress(AddressOf HandleAttack2)
    HandleDataSub(SNpcAttack1) = GetAddress(AddressOf HandleNpcAttack1)
    HandleDataSub(SNpcAttack2) = GetAddress(AddressOf HandleNpcAttack2)
```
In modEnumerations replaced
```
SAttack
SNpcAttack
```
With

```
SAttack1
SAttack2
SNpcAttack1
SNpcAttack2
```
And

```
CAttack
```
With

```
CAttack1
CAttack2
```

Server:

in modHandleData change

```
HandleDataSub(CAttack) = GetAddress(AddressOf HandleAttack)
```
To

```
    HandleDataSub(CAttack1) = GetAddress(AddressOf HandleAttack1)
    HandleDataSub(CAttack2) = GetAddress(AddressOf HandleAttack2)
```
Sub HandleAttack replaced with 2 subs

```
' ::::::::::::::::::::::::::
' :: Player attack packet ::
' ::::::::::::::::::::::::::
Sub HandleAttack1(ByVal index As Long, ByRef Data() As Byte, ByVal StartAddr As Long, ByVal ExtraVar As Long)
    Dim i As Long
    Dim n As Long
    Dim Damage As Long
    Dim TempIndex As Long
    Dim x As Long, y As Long

    ' can't attack whilst casting
    If TempPlayer(index).spellBuffer.Spell > 0 Then Exit Sub

    ' can't attack whilst stunned
    If TempPlayer(index).StunDuration > 0 Then Exit Sub

    ' Send this packet so they can see the person attacking
    'SendAttack Index

    ' Try to attack a player
    For i = 1 To Player_HighIndex
        TempIndex = i

        ' Make sure we dont try to attack ourselves
        If TempIndex <> index Then
            TryPlayerAttackPlayer index, i
        End If
    Next

    ' Try to attack a npc
    For i = 1 To MAX_MAP_NPCS
        TryPlayerAttackNpc index, i
    Next

    ' Check tradeskills
    Select Case GetPlayerDir(index)
        Case DIR_UP

            If GetPlayerY(index) = 0 Then Exit Sub
            x = GetPlayerX(index)
            y = GetPlayerY(index) - 1
        Case DIR_DOWN

            If GetPlayerY(index) = Map(GetPlayerMap(index)).MaxY Then Exit Sub
            x = GetPlayerX(index)
            y = GetPlayerY(index) + 1
        Case DIR_LEFT

            If GetPlayerX(index) = 0 Then Exit Sub
            x = GetPlayerX(index) - 1
            y = GetPlayerY(index)
        Case DIR_RIGHT

            If GetPlayerX(index) = Map(GetPlayerMap(index)).MaxX Then Exit Sub
            x = GetPlayerX(index) + 1
            y = GetPlayerY(index)
    End Select

    CheckResource index, x, y
End Sub
```
```
' ::::::::::::::::::::::::::
' :: Player attack packet ::
' ::::::::::::::::::::::::::
Sub HandleAttack2(ByVal index As Long, ByRef Data() As Byte, ByVal StartAddr As Long, ByVal ExtraVar As Long)
    Dim i As Long
    Dim n As Long
    Dim Damage As Long
    Dim TempIndex As Long
    Dim x As Long, y As Long

    ' can't attack whilst casting
    If TempPlayer(index).spellBuffer.Spell > 0 Then Exit Sub

    ' can't attack whilst stunned
    If TempPlayer(index).StunDuration > 0 Then Exit Sub

    ' Send this packet so they can see the person attacking
    'SendAttack Index

    ' Try to attack a player
    For i = 1 To Player_HighIndex
        TempIndex = i

        ' Make sure we dont try to attack ourselves
        If TempIndex <> index Then
            TryPlayerAttackPlayer index, i
        End If
    Next

    ' Try to attack a npc
    For i = 1 To MAX_MAP_NPCS
        TryPlayerAttackNpc index, i
    Next

    ' Check tradeskills
    Select Case GetPlayerDir(index)
        Case DIR_UP

            If GetPlayerY(index) = 0 Then Exit Sub
            x = GetPlayerX(index)
            y = GetPlayerY(index) - 1
        Case DIR_DOWN

            If GetPlayerY(index) = Map(GetPlayerMap(index)).MaxY Then Exit Sub
            x = GetPlayerX(index)
            y = GetPlayerY(index) + 1
        Case DIR_LEFT

            If GetPlayerX(index) = 0 Then Exit Sub
            x = GetPlayerX(index) - 1
            y = GetPlayerY(index)
        Case DIR_RIGHT

            If GetPlayerX(index) = Map(GetPlayerMap(index)).MaxX Then Exit Sub
            x = GetPlayerX(index) + 1
            y = GetPlayerY(index)
    End Select

    CheckResource index, x, y
End Sub
```
In ModEnumerations

```
    SAttack
    SNpcAttack
```
To

```
    SAttack1
    SAttack2
    SNpcAttack1
    SNpcAttack2
```
And

```
CAttack
```
To

```
    CAttack1
    CAttack2
```
In ModCombat

```
' Send this packet so they can see the npc attacking
    Set Buffer = New clsBuffer
    Buffer.WriteLong SNpcAttack
```
To```
    ' Send this packet so they can see the npc attacking
    Set Buffer = New clsBuffer
    Buffer.WriteLong SNpcAttack1
    Buffer.WriteLong SNpcAttack2
```
Link to comment
Share on other sites

When you first download EO you have Ctrl for attacking but nothing else. This tutorial helps you add another one with separate controls. Of course it doesn't have to be punching and kicking, it could be vertical sword slash/horizontal sword slash or Punch, headbutt, whatever you decide to put on your sprite sheet.

However there's no special effect to the extra attack, it just looks cool, mixes up the combat a bit. You'd have to add to it, which I will leave up to your own imagination.
Link to comment
Share on other sites

@-Jake-:

> Thanks for the idea. I'll be trying to edit this (and da_gad_pader's tut) to actually work in an online setting. Right now its more of a single player rpg kind of code.

Thanks :) Let me know when you figure it out so I can update this tut.
Link to comment
Share on other sites

I'm obviously still learning, I just wanted to share something I had done. As soon as I know a better way to do this I'll update the thread, but right now I don't so that's why in God's name I have separate packets and duplicated stuff.
Link to comment
Share on other sites

@Liger:

> I'm obviously still learning, I just wanted to share something I had done. As soon as I know a better way to do this I'll update the thread, but right now I don't so that's why in God's name I have separate packets and duplicated stuff.

And now you know better. Go fix it.
Link to comment
Share on other sites

  • 3 weeks later...

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...