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

[EO2.0]Ranged Projectiles(Arrows, Bullets and more)[RELEASE]


evilbunnie
 Share

Recommended Posts

**Ranged projectiles for EO**

>! ![](http://www.freemmorpgmaker.com/files/imagehost/pics/04c0be81bb37323cdd86e6c0a6686390.PNG)
Sorry for the bad picture, I'm going to post a better one ASAP.
_**Description & Use**_
At present time EO lacks the presence of projectiles, which has limited the possibilities for many games. I have decided to release this system as I would personally like to see more gun games and arrow games that allow ranged combat instead of close up battle. This system allows the use of Projectiles. A projectile for example is an Arrow or a bullet. This system is fairly basic but allows for ranged combat.

To use the this system, once all of the source edits have been installed, you must enter the Item Editor and set each variable based on your needs for specific gun. You must set the item type to weapon.

If you would like to skip this tutorial and download a copy with the tutorial already inserted, scroll down and click on the attached zip file.

* **Speed**: The speed of the projectile when shot. [The higher the number the slower it is]
* **Range**: The range of tiles the projectile can travel at most. [One number per tile]
* **Pic**: The projectile image, which can be found in client> data files> projectiles.
* **Damage**: The damage the projectile inflicts on hit NPC/Player.

Next, equip the said item onto your character, face an enemy and press control. Nice job, mate.

_**Source work**_
**Client Work**

First create a folder in data files\graphics\projectiles and place the attached arrow example(1.bmp)

In **modConstants** _Under:_
```
Public Const MAX_PARTY_MEMBERS As Long = 4
```_Insert:_
```
Public Const MAX_PLAYER_PROJECTILES As Long = 20
```
In **Sub Main** _Under:_
```
Call CheckFaces
```_Insert:_
```
Call CheckProjectiles
```
In **Sub ItemEditorInit** _Under:_
```
frmEditor_Item.scrlPaperdoll = .Paperdoll
```_Insert:_
```

If frmEditor_Item.cmbType.ListIndex = ITEM_TYPE_WEAPON Then
    frmEditor_Item.Frame4.Visible = True
    With Item(EditorIndex).ProjecTile
          frmEditor_Item.scrlProjectileDamage.Value = .Damage
          frmEditor_Item.scrlProjectilePic.Value = .Pic
          frmEditor_Item.scrlProjectileRange.Value = .Range
          frmEditor_Item.scrlProjectileSpeed.Value = .Speed
    End With
End If

```Then _Under **in the SAME sub**:_
```
frmEditor_Item.fraEquipment.Visible = False
```_Insert:_
```
frmEditor_Item.Frame4.Visible = False
```
In **modDirectDraw7** _Under_
```
Public DDS_Face() As DirectDrawSurface7
```_Insert:_
```
Public DDS_Projectile() As DirectDrawSurface7
```Then _Under:_
```
Public DDSD_Face() As DDSURFACEDESC2
```_Insert:_
```
Public DDSD_Projectile() As DDSURFACEDESC2
```Then _Under:_
```
Public NumFaces As Long
```_Insert:_
```
Public NumProjectiles As Long
```
In **Sub DestroyDirectDraw** _Under:_
```
For i = 1 To NumFaces
  Set DDS_Face(i) = Nothing
  ZeroMemory ByVal VarPtr(DDSD_Face(i)), LenB(DDSD_Face(i))
Next
```_Insert:_
```

For i = 1 To NumProjectiles
    Set DDS_Projectile(i) = Nothing
    ZeroMemory ByVal VarPtr(DDSD_Projectile(i)), LenB(DDSD_Projectile(i))
Next
```
In **modDirectDraw7** _insert:_
```
' player Projectiles
Public Sub BltProjectile(ByVal Index As Long, ByVal PlayerProjectile As Long)
Dim x As Long, y As Long, PicNum As Long, i As Long
Dim rec As DxVBLib.RECT

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

    ' check for subscript error
    If Index < 1 Or PlayerProjectile < 1 Or PlayerProjectile > MAX_PLAYER_PROJECTILES Then Exit Sub

    ' check to see if it's time to move the Projectile
    If GetTickCount > Player(Index).ProjecTile(PlayerProjectile).TravelTime Then
        With Player(Index).ProjecTile(PlayerProjectile)
            ' set next travel time and the current position and then set the actual direction based on RMXP arrow tiles.
            Select Case .Direction
                ' down
                Case 0
                    .y = .y + 1
                    ' check if they reached maxrange
                    If .y = (GetPlayerY(Index) + .Range) + 1 Then ClearProjectile Index, PlayerProjectile: Exit Sub
                ' up
                Case 1
                    .y = .y - 1
                    ' check if they reached maxrange
                    If .y = (GetPlayerY(Index) - .Range) - 1 Then ClearProjectile Index, PlayerProjectile: Exit Sub
                ' right
                Case 2
                    .x = .x + 1
                    ' check if they reached max range
                    If .x = (GetPlayerX(Index) + .Range) + 1 Then ClearProjectile Index, PlayerProjectile: Exit Sub
                ' left
                Case 3
                    .x = .x - 1
                    ' check if they reached maxrange
                    If .x = (GetPlayerX(Index) - .Range) - 1 Then ClearProjectile Index, PlayerProjectile: Exit Sub
            End Select
            .TravelTime = GetTickCount + .Speed
        End With
    End If

    ' set the x, y & pic values for future reference
    x = Player(Index).ProjecTile(PlayerProjectile).x
    y = Player(Index).ProjecTile(PlayerProjectile).y
    PicNum = Player(Index).ProjecTile(PlayerProjectile).Pic

    ' check if left map
    If x > Map.MaxX Or y > Map.MaxY Or x < 0 Or y < 0 Then
        ClearProjectile Index, PlayerProjectile
        Exit Sub
    End If

    ' check if we hit a block
    If Map.Tile(x, y).Type = TILE_TYPE_BLOCKED Then
        ClearProjectile Index, PlayerProjectile
        Exit Sub
    End If

    ' check for player hit
    For i = 1 To Player_HighIndex
        If x = GetPlayerX(i) And y = GetPlayerY(i) Then
            ' they're hit, remove it
            If Not x = Player(MyIndex).x Or Not y = GetPlayerY(MyIndex) Then
                ClearProjectile Index, PlayerProjectile
                Exit Sub
            End If
        End If
    Next

    ' check for npc hit
    For i = 1 To MAX_MAP_NPCS
        If x = MapNpc(i).x And y = MapNpc(i).y Then
            ' they're hit, remove it
            ClearProjectile Index, PlayerProjectile
            Exit Sub
        End If
    Next

    ' if projectile is not loaded, load it, female dog.
    If DDS_Projectile(PicNum) Is Nothing Then
        Call InitDDSurf("projectiles\" & PicNum, DDSD_Projectile(PicNum), DDS_Projectile(PicNum))
    End If

    ' get positioning in the texture
    With rec
        .top = 0
        .Bottom = SIZE_Y
        .Left = Player(Index).ProjecTile(PlayerProjectile).Direction * SIZE_X
        .Right = .Left + SIZE_X
    End With

    ' blt the projectile
    Call Engine_BltFast(ConvertMapX(x * PIC_X), ConvertMapY(y * PIC_Y), DDS_Projectile(PicNum), rec, DDBLTFAST_WAIT Or DDBLTFAST_SRCCOLORKEY)

    ' Error handler
    Exit Sub
errorhandler:
    HandleError "BltProjectile", "modDirectDraw7", Err.Number, Err.Description, Err.Source, Err.HelpContext
    Err.Clear
    Exit Sub
End Sub

```
In **Sub Render_Graphics** _Under:_
```
    ' draw animations
    If NumAnimations > 0 Then
        For i = 1 To MAX_BYTE
            If AnimInstance(i).Used(0) Then
                BltAnimation i, 0
            End If
        Next
    End If

```_Insert:_
```
    ' blt projec tiles for each player
    For i = 1 To Player_HighIndex
        For x = 1 To MAX_PLAYER_PROJECTILES
            If Player(i).ProjecTile(x).Pic > 0 Then
                BltProjectile i, x
            End If
        Next
    Next

```
In **modTypes** _Above:_
```
Private Type PlayerRec
```_Insert:_
```
Public Type ProjectileRec
    TravelTime As Long
    Direction As Long
    x As Long
    y As Long
    Pic As Long
    Range As Long
    Damage As Long
    Speed As Long
End Type

```
In **Private Type PlayerRec** _Before:_
```
End Type
```_Insert:_
```
    ' projectiles
    ProjecTile(1 To MAX_PLAYER_PROJECTILES) As ProjectileRec

```
In **Private Type ItemRec** _Before:_
```
End Type
```_Insert:_
```
    ProjecTile As ProjectileRec

```
In **modDatabase** _Insert:_
```

' projectiles
Public Sub CheckProjectiles()
Dim i As Long

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

    i = 1

    While FileExist(GFX_PATH & "Projectiles\" & i & GFX_EXT)
        NumProjectiles = NumProjectiles + 1
        i = i + 1
    Wend

    If NumProjectiles = 0 Then Exit Sub

    ReDim DDS_Projectile(1 To NumProjectiles)
    ReDim DDSD_Projectile(1 To NumProjectiles)

    ' Error handler
    Exit Sub
errorhandler:
    HandleError "CheckItems", "modDatabase", Err.Number, Err.Description, Err.Source, Err.HelpContext
    Err.Clear
    Exit Sub
End Sub

Sub ClearProjectile(ByVal Index As Long, ByVal PlayerProjectile As Long)
    ' If debug mode, handle error then exit out
    If Options.Debug = 1 Then On Error GoTo errorhandler

    With Player(Index).ProjecTile(PlayerProjectile)
        .Direction = 0
        .Pic = 0
        .TravelTime = 0
        .x = 0
        .y = 0
        .Range = 0
        .Damage = 0
        .Speed = 0
    End With

    ' Error handler
    Exit Sub
errorhandler:
    HandleError "ClearProjectile", "modDatabase", Err.Number, Err.Description, Err.Source, Err.HelpContext
    Err.Clear
    Exit Sub
End Sub

```
Replace **Sub CheckAttack** with:
```
Public Sub CheckAttack()
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 ControlDown 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).Attacking = 0 Then

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

                If GetPlayerEquipment(MyIndex, Weapon) > 0 Then
                    If Item(GetPlayerEquipment(MyIndex, Weapon)).ProjecTile.Pic > 0 Then
                        ' projectile
                        Set Buffer = New clsBuffer
                            Buffer.WriteLong CProjecTileAttack
                            SendData Buffer.ToArray()
                            Set Buffer = Nothing
                            Exit Sub
                    End If
                End If

                ' non projectile
                Set Buffer = New clsBuffer
                Buffer.WriteLong CAttack
                SendData Buffer.ToArray()
                Set Buffer = Nothing
            End If
        End If
    End If

    ' Error handler
    Exit Sub
errorhandler:
    HandleError "CheckAttack", "modGameLogic", Err.Number, Err.Description, Err.Source, Err.HelpContext
    Err.Clear
    Exit Sub
End Sub

```
In **Public Enum ServerPackets** _Before:_
```
SMSG_COUNT
```_Insert:_
```
    SHandleProjectile

```
In **Public Enum ClientPackets** _Before:_
```
SMSG_COUNT
```_Insert:_
```
    CProjecTileAttack

```
In **Sub InitMessages** _After:_
```
HandleDataSub(SPartyVitals) = GetAddress(AddressOf HandlePartyVitals)
```_Insert:_
```
    HandleDataSub(SHandleProjectile) = GetAddress(AddressOf HandleProjectile)
```
In **modHandleData** _Insert:_
```
Sub HandleProjectile(ByVal Index As Long, ByRef Data() As Byte, ByVal StartAddr As Long, ByVal ExtraVar As Long)
Dim PlayerProjectile As Long
Dim Buffer As clsBuffer

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

    ' create a new instance of the buffer
    Set Buffer = New clsBuffer

    ' read bytes from data()
    Buffer.WriteBytes Data()

    ' recieve projectile number
    PlayerProjectile = Buffer.ReadLong
    Index = Buffer.ReadLong

    ' populate the values
    With Player(Index).ProjecTile(PlayerProjectile)

        ' set the direction
        .Direction = Buffer.ReadLong

        ' set the direction to support file format
        Select Case .Direction
            Case DIR_DOWN
                .Direction = 0
            Case DIR_UP
                .Direction = 1
            Case DIR_RIGHT
                .Direction = 2
            Case DIR_LEFT
                .Direction = 3
        End Select

        ' set the pic
        .Pic = Buffer.ReadLong
        ' set the coordinates
        .x = GetPlayerX(Index)
        .y = GetPlayerY(Index)
        ' get the range
        .Range = Buffer.ReadLong
        ' get the damge
        .Damage = Buffer.ReadLong
        ' get the speed
        .Speed = Buffer.ReadLong

    End With

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

```
**Server Work**

In **modConstants** _before:_
```
Public Const MAX_PARTY_MEMBERS As Long = 4
```_Insert_:
```
Public Const MAX_PLAYER_PROJECTILES As Long = 20
```
In **modDatabase** _insert:_
```
Sub ClearProjectile(ByVal Index As Long, ByVal PlayerProjectile As Long)
    ' clear the projectile
    With TempPlayer(Index).ProjecTile(PlayerProjectile)
        .Direction = 0
        .Pic = 0
        .TravelTime = 0
        .x = 0
        .y = 0
        .Range = 0
        .Damage = 0
        .Speed = 0
    End With
End Sub

```
In **modGameLogic** _insert:_
```
Public Sub HandleProjecTile(ByVal Index As Long, ByVal PlayerProjectile As Long)
Dim x As Long, y As Long, i As Long

    ' check for subscript out of range
    If Index < 1 Or Index > MAX_PLAYERS Or PlayerProjectile < 1 Or PlayerProjectile > MAX_PLAYER_PROJECTILES Then Exit Sub

    ' check to see if it's time to move the Projectile
    If GetTickCount > TempPlayer(Index).ProjecTile(PlayerProjectile).TravelTime Then
        With TempPlayer(Index).ProjecTile(PlayerProjectile)
            ' set next travel time and the current position and then set the actual direction based on RMXP arrow tiles.
            Select Case .Direction
                ' down
                Case DIR_DOWN
                    .y = .y + 1
                    ' check if they reached maxrange
                    If .y = (GetPlayerY(Index) + .Range) + 1 Then ClearProjectile Index, PlayerProjectile: Exit Sub
                ' up
                Case DIR_UP
                    .y = .y - 1
                    ' check if they reached maxrange
                    If .y = (GetPlayerY(Index) - .Range) - 1 Then ClearProjectile Index, PlayerProjectile: Exit Sub
                ' right
                Case DIR_RIGHT
                    .x = .x + 1
                    ' check if they reached max range
                    If .x = (GetPlayerX(Index) + .Range) + 1 Then ClearProjectile Index, PlayerProjectile: Exit Sub
                ' left
                Case DIR_LEFT
                    .x = .x - 1
                    ' check if they reached maxrange
                    If .x = (GetPlayerX(Index) - .Range) - 1 Then ClearProjectile Index, PlayerProjectile: Exit Sub
            End Select
            .TravelTime = GetTickCount + .Speed
        End With
    End If

    x = TempPlayer(Index).ProjecTile(PlayerProjectile).x
    y = TempPlayer(Index).ProjecTile(PlayerProjectile).y

    ' check if left map
    If x > Map(GetPlayerMap(Index)).MaxX Or y > Map(GetPlayerMap(Index)).MaxY Or x < 0 Or y < 0 Then
        ClearProjectile Index, PlayerProjectile
        Exit Sub
    End If

    ' check if hit player
    For i = 1 To Player_HighIndex
        ' make sure they're actually playing
        If IsPlaying(i) Then
            ' check coordinates
            If x = Player(i).x And y = GetPlayerY(i) Then
                ' make sure it's not the attacker
                If Not x = Player(Index).x Or Not y = GetPlayerY(Index) Then
                    ' check if player can attack
                    If CanPlayerAttackPlayer(Index, i, False, True) = True Then
                        ' attack the player and kill the project tile
                        PlayerAttackPlayer Index, i, TempPlayer(Index).ProjecTile(PlayerProjectile).Damage
                        ClearProjectile Index, PlayerProjectile
                        Exit Sub
                    Else
                        ClearProjectile Index, PlayerProjectile
                        Exit Sub
                    End If
                End If
            End If
        End If
    Next

    ' check for npc hit
    For i = 1 To MAX_MAP_NPCS
        If x = MapNpc(GetPlayerMap(Index)).Npc(i).x And y = MapNpc(GetPlayerMap(Index)).Npc(i).y Then
            ' they're hit, remove it and deal that damage ;)
            If CanPlayerAttackNpc(Index, i, True) Then
                PlayerAttackNpc Index, i, TempPlayer(Index).ProjecTile(PlayerProjectile).Damage
                ClearProjectile Index, PlayerProjectile
                Exit Sub
            Else
                ClearProjectile Index, PlayerProjectile
                Exit Sub
            End If
        End If
    Next

    ' hit a block
    If Map(GetPlayerMap(Index)).Tile(x, y).Type = TILE_TYPE_BLOCKED Then
        ' hit a block, clear it.
        ClearProjectile Index, PlayerProjectile
        Exit Sub
    End If

End Sub

```
In **Sub InitMessages** _after:_
```
HandleDataSub(CPartyLeave) = GetAddress(AddressOf HandlePartyLeave)
```_Insert:_
```
HandleDataSub(CProjecTileAttack) = GetAddress(AddressOf HandleProjecTileAttack)

```
In **modHandleData** _insert:_
```
Private Sub HandleProjecTileAttack(ByVal Index As Long, ByRef Data() As Byte, ByVal StartAddr As Long, ByVal ExtraVar As Long)
Dim curProjecTile As Long, i As Long, CurEquipment As Long

    ' prevent subscript
    If Index > MAX_PLAYERS Or Index < 1 Then Exit Sub

    ' get the players current equipment
    CurEquipment = GetPlayerEquipment(Index, Weapon)

    ' check if they've got equipment
    If CurEquipment < 1 Or CurEquipment > MAX_ITEMS Then Exit Sub

    ' set the curprojectile
    For i = 1 To MAX_PLAYER_PROJECTILES
        If TempPlayer(Index).ProjecTile(i).Pic = 0 Then
            ' just incase there is left over data
            ClearProjectile Index, i
            ' set the curprojtile
            curProjecTile = i
            Exit For
        End If
    Next

    ' check for subscript
    If curProjecTile < 1 Then Exit Sub

    ' populate the data in the player rec
    With TempPlayer(Index).ProjecTile(curProjecTile)
        .Damage = Item(CurEquipment).ProjecTile.Damage
        .Direction = GetPlayerDir(Index)
        .Pic = Item(CurEquipment).ProjecTile.Pic
        .Range = Item(CurEquipment).ProjecTile.Range
        .Speed = Item(CurEquipment).ProjecTile.Speed
        .x = GetPlayerX(Index)
        .y = GetPlayerY(Index)
    End With

    ' trololol, they have no more projectile space left
    If curProjecTile < 1 Or curProjecTile > MAX_PLAYER_PROJECTILES Then Exit Sub

    ' update the projectile on the map
    SendProjectileToMap Index, curProjecTile

End Sub

```

In **modServerTcp** _insert:_
```
Sub SendProjectileToMap(ByVal Index As Long, ByVal PlayerProjectile As Long)
Dim Buffer As clsBuffer

    Set Buffer = New clsBuffer
    Buffer.WriteLong SHandleProjectile
    Buffer.WriteLong PlayerProjectile
    Buffer.WriteLong Index
    With TempPlayer(Index).ProjecTile(PlayerProjectile)
        Buffer.WriteLong .Direction
        Buffer.WriteLong .Pic
        Buffer.WriteLong .Range
        Buffer.WriteLong .Damage
        Buffer.WriteLong .Speed
    End With
    SendDataToMap GetPlayerMap(Index), Buffer.ToArray()
    Set Buffer = Nothing
End Sub

```
In **modTypes** _before:_
```
Private Type PlayerRec
```_Insert:_
```
Public Type ProjectileRec
    TravelTime As Long
    Direction As Long
    x As Long
    y As Long
    Pic As Long
    Range As Long
    Damage As Long
    Speed As Long
End Type

```In **Public Type TempPlayerRec** _insert:_
```
    ProjecTile(1 To MAX_PLAYER_PROJECTILES) As ProjectileRec
```In **Private Type ItemRec**_before:_
```
End Type
```_Insert:_
```
    ProjecTile As ProjectileRec
```
In **Sub ServerLoop** _before:_
```
' Checks to update player vitals every 5 seconds - Can be tweaked
```_Insert:_
```
        For i = 1 To Player_HighIndex
            If IsPlaying(i) Then
                For x = 1 To MAX_PLAYER_PROJECTILES
                    If TempPlayer(i).ProjecTile(x).Pic > 0 Then
                        ' handle the projec tile
                        HandleProjecTile i, x
                    End If
                Next
            End If
        Next

```
In **Public Enum ServerPackets** _before:_
```
SMSG_COUNT
```_Insert:_
```
    SHandleProjectile

```
In **Public Enum ClientPackets** _before:_
```
SMSG_COUNT
```_Insert:_
```
    CProjecTileAttack

```
In **Sub PlayerAttackNpc** _before:_
```
    Name = Trim$(Npc(npcNum).Name)
```_Insert:_
```
    If npcNum < 1 Then Exit Sub
```
In **Function CanPlayerAttackPlayer** _replace_ the entire procedure with:
```

Function CanPlayerAttackPlayer(ByVal attacker As Long, ByVal victim As Long, Optional ByVal IsSpell As Boolean = False, Optional ByVal IsProjectile As Boolean = False) As Boolean

    If Not IsSpell And Not IsProjectile 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 And Not IsProjectile 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

```
**Client Form Work**
Remove frmEditor_Item from your client, and replace it with the attached form.
Or follow these simple steps:

In **frmEditor_Item** _create_ a replica of the highlighted box:

>! ![](http://www.freemmorpgmaker.com/files/imagehost/pics/767888c537fd748c5974777d416d5176.PNG)

In **frmEditor_Item's** _source code_ insert:
```
' projectile
Private Sub scrlProjectileDamage_Change()
    ' If debug mode, handle error then exit out
    If Options.Debug = 1 Then On Error GoTo errorhandler

    If EditorIndex = 0 Or EditorIndex > MAX_ITEMS Then Exit Sub
    lblProjectileDamage.Caption = "Damage: " & scrlProjectileDamage.Value
    Item(EditorIndex).ProjecTile.Damage = scrlProjectileDamage.Value

    ' Error handler
    Exit Sub
errorhandler:
    HandleError "scrlProjectilePic_Change", "frmEditor_Item", Err.Number, Err.Description, Err.Source, Err.HelpContext
    Err.Clear
    Exit Sub
End Sub

' projectile
Private Sub scrlProjectilePic_Change()
    ' If debug mode, handle error then exit out
    If Options.Debug = 1 Then On Error GoTo errorhandler

    If EditorIndex = 0 Or EditorIndex > MAX_ITEMS Then Exit Sub
    lblProjectilePiC.Caption = "Pic: " & scrlProjectilePic.Value
    Item(EditorIndex).ProjecTile.Pic = scrlProjectilePic.Value

    ' Error handler
    Exit Sub
errorhandler:
    HandleError "scrlProjectilePic_Change", "frmEditor_Item", Err.Number, Err.Description, Err.Source, Err.HelpContext
    Err.Clear
    Exit Sub
End Sub

' ProjecTile
Private Sub scrlProjectileRange_Change()
    ' If debug mode, handle error then exit out
    If Options.Debug = 1 Then On Error GoTo errorhandler

    If EditorIndex = 0 Or EditorIndex > MAX_ITEMS Then Exit Sub
    lblProjectileRange.Caption = "Range: " & scrlProjectileRange.Value
    Item(EditorIndex).ProjecTile.Range = scrlProjectileRange.Value

    ' Error handler
    Exit Sub
errorhandler:
    HandleError "scrlProjectileRange_Change", "frmEditor_Item", Err.Number, Err.Description, Err.Source, Err.HelpContext
    Err.Clear
    Exit Sub
End Sub

' projectile
Private Sub scrlProjectileSpeed_Change()
    ' If debug mode, handle error then exit out
    If Options.Debug = 1 Then On Error GoTo errorhandler

    If EditorIndex = 0 Or EditorIndex > MAX_ITEMS Then Exit Sub
    lblProjectilesSpeed.Caption = "Speed: " & scrlProjectileSpeed.Value
    Item(EditorIndex).ProjecTile.Speed = scrlProjectileSpeed.Value

    ' Error handler
    Exit Sub
errorhandler:
    HandleError "scrlRarity_Change", "frmEditor_Item", Err.Number, Err.Description, Err.Source, Err.HelpContext
    Err.Clear
    Exit Sub
End Sub

```
Then **replace**
```
Private Sub cmbType_Click()

```_With:_
```
Private Sub cmbType_Click()
    ' If debug mode, handle error then exit out
    If Options.Debug = 1 Then On Error GoTo errorhandler

    If EditorIndex = 0 Or EditorIndex > MAX_ITEMS Then Exit Sub

    If (cmbType.ListIndex >= ITEM_TYPE_WEAPON) And (cmbType.ListIndex <= ITEM_TYPE_SHIELD) Then
        fraEquipment.Visible = True
        'scrlDamage_Change
        If cmbType.ListIndex = ITEM_TYPE_WEAPON Then
            frame4.Visible = True
        End If
    Else
        fraEquipment.Visible = False
        frame4.Visible = False
    End If

    If cmbType.ListIndex = ITEM_TYPE_CONSUME Then
        fraVitals.Visible = True
        'scrlVitalMod_Change
    Else
        fraVitals.Visible = False
    End If

    If (cmbType.ListIndex = ITEM_TYPE_SPELL) Then
        fraSpell.Visible = True
    Else
        fraSpell.Visible = False
    End If

    Item(EditorIndex).Type = cmbType.ListIndex

    ' Error handler
    Exit Sub
errorhandler:
    HandleError "cmbType_Click", "frmEditor_Item", Err.Number, Err.Description, Err.Source, Err.HelpContext
    Err.Clear
    Exit Sub
End Sub
```
Erwin's fix for blocking of arrows;http://www.touchofdeathforums.com/smf/index.php/topic,73708.msg822198.html#msg822198 THANKS!

**Be sure to give me credit**
Link to comment
Share on other sites

  • Replies 232
  • Created
  • Last Reply

Top Posters In This Topic

@DishWasher:

> hey,asnwome release there :B
>
> ps:I just test your arrow demo project and I found a error;if the map is dynamic,the arrows dont work/show
>
> ps2: realy cool the arrow speed *-*

Really? I guess I'll have to fix that then :P I found it's because I used the static MAX values. I'll fix that now.

Warning - while you were typing a new reply has been posted. You may wish to review your post.
Lol you beat me robin
Link to comment
Share on other sites

Thank you very much for your kind remarks guys.

I've updated all the fixes. ^_^ and the zip file.

Also octo, azure means 'He's done this feature before'

Also, if anyone wants to make me some screenshots, feel free to PM them to me as my screen is too small atm.
Link to comment
Share on other sites

wow.wow.oh wow.i was just begging someone for it earlier and here it is.Captain Wabbit YOU ARE THE BEST!!!!!i was just begging kibblez to make it for me and its right here.unbelievable.people are making more and more edit about eclipse and every one is better than the last but yours just saved me a lot of time.thank you thank you thank you.and by the way i feel like a begger for begging kibblez for it.this will make the recource board and the question/answers board a lot quieter.rose was planning to add this in Eclipse Galaxy by the way.
Link to comment
Share on other sites

A nice job, i have made one of theese for my game. That anoys me now because i wasn't planning to release mine and you did :/. Anyway it looks nice, although it doesn't have all of the features mine has though :3\. Good work.
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...