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

[All versions] Spell path algorithm


tslusny
 Share

Recommended Posts

What this does? It will simply disable casting spells throught walls or from corners. It is unreal when you can cast spell on someone who is for example behind castle wall, isn´t it?

This is only **server side** edit:

First, add this sub at bottom of modGameLogic:

```

Public Function isPathCleared(ByVal Index As Long, ByVal x1 As Long, ByVal y1 As Long, ByVal x2 As Long, ByVal y2 As Long) As Boolean

Dim DirX As Integer

Dim DirY As Integer

Dim IsXDirRight As Integer ' Yeah, it just makes it easier

Dim IsYDirDown As Integer

Dim CurX As Long

Dim CurY As Long

Dim XInSquare As Single ' Fraction of the square we're looking at, CurX,CurY

Dim YInSquare As Single

Dim TestX As Single ' TestX is the X value when Y = 0 or Y = 1, whichever is important

Dim TestY As Single

Dim slope As Single

' How much y for 1 x

CurX = x1

CurY = y1

XInSquare = 0.5 ' Middle of x1

YInSquare = 0.5 ' Middle of y1

If x1 = x2 Then

If y1 = y2 Then

isPathCleared = True

Exit Function

End If

End If

If x2 - x1 = 0 Then ' Would be divide by zero

' Vertical only

DirX = 0

IsXDirRight = 0

If y2 > y1 Then

DirY = 1

IsYDirDown = 1

Else

DirY = -1

IsYDirDown = 0

End If

Do

' Move to the next square

CurY = CurY + DirY

' Check new square

If CurY = y2 Then

Exit Do

' ======

ElseIf Map(GetPlayerMap(Index)).Tile(CurX, CurY).Type = TILE_TYPE_BLOCKED Or Map(GetPlayerMap(Index)).Tile(CurX, CurY).Type = TILE_TYPE_RESOURCE Then

' ElseIf Blocked(CurX, CurY) Then

' /=====

isPathCleared = False

Exit Function

End If

Loop While (CurY <> y2)

ElseIf y2 - y1 = 0 Then

' Horiz only

DirY = 0

IsYDirDown = 0

If x2 > x1 Then

DirX = 1

IsXDirRight = 1

Else

DirX = -1

IsXDirRight = 0

End If

Do

' Move to the next square

CurX = CurX + DirX

' Check new square

If CurX = x2 Then

Exit Do

' ======

ElseIf Map(GetPlayerMap(Index)).Tile(CurX, CurY).Type = TILE_TYPE_BLOCKED Or Map(GetPlayerMap(Index)).Tile(CurX, CurY).Type = TILE_TYPE_RESOURCE Then

' ElseIf Blocked(CurX, CurY) Then

' /=====

isPathCleared = False

Exit Function

End If

Loop

Else

' Some sort of diagonal

If x2 > x1 Then

DirX = 1

IsXDirRight = 1

Else

DirX = -1

IsXDirRight = 0

End If

If y2 > y1 Then

DirY = 1

IsYDirDown = 1

Else

DirY = -1

IsYDirDown = 0

End If

slope = (y2 - y1) / (x2 - x1)

Do

' Move to the next square

If IsXDirRight Then

TestY = (1 - XInSquare) * slope + YInSquare

Else

TestY = -XInSquare * slope + YInSquare

End If

If IsYDirDown Then

TestX = (1 - YInSquare) / slope + XInSquare

Else

TestX = -YInSquare / slope + XInSquare

End If

If (TestX > 0 And TestX < 1) Then

' Go up or down

CurY = CurY + DirY

' set the coords for the new square

XInSquare = TestX

YInSquare = 1 - IsYDirDown

ElseIf (TestY > 0 And TestY < 1) Then

' Go left or right

CurX = CurX + DirX

' set the coords for the new square

XInSquare = 1 - IsXDirRight

YInSquare = TestY

Else

' Go diagonally

CurX = CurX + DirX

CurY = CurY + DirY

' set the coords for the new square

XInSquare = 1 - IsXDirRight

YInSquare = 1 - IsYDirDown

End If

' Check new square

If CurX = x2 And CurY = y2 Then

Exit Do

' ======

ElseIf Map(GetPlayerMap(Index)).Tile(CurX, CurY).Type = TILE_TYPE_BLOCKED Or Map(GetPlayerMap(Index)).Tile(CurX, CurY).Type = TILE_TYPE_RESOURCE Then

' ElseIf Blocked(CurX, CurY) Then

' /=====

isPathCleared = False

Exit Function

End If

Loop

End If

isPathCleared = True

End Function

```

Then search for Sub CastSpell and in this sub search for this:

```

Case 1, 3 ' self-cast AOE & targetted AOE

If SpellCastType = 1 Then

x = GetPlayerX(Index)

y = GetPlayerY(Index)

ElseIf SpellCastType = 3 Then

If TargetType = 0 Then Exit Sub

If target = 0 Then Exit Sub

If TargetType = targetPlayer Then

x = GetPlayerX(target)

y = GetPlayerY(target)

Else

x = MapNpc(MapNum).Npc(target).x

y = MapNpc(MapNum).Npc(target).y

End If

If Not isInRange(Range, GetPlayerX(Index), GetPlayerY(Index), x, y) Then

PlayerMsg Index, "Target not in range.", BrightRed

SendClearSpellBuffer Index

End If

```

And add this **under** it:

```

If Not isPathCleared(Index, GetPlayerX(Index), GetPlayerY(Index), x, y) Then

PlayerMsg Index, "Can not reach target.", BrightRed

SendClearSpellBuffer Index

Exit Sub

End If

```

Now search for this:

```

Case 2 ' targetted

If TargetType = 0 Then Exit Sub

If target = 0 Then Exit Sub

If TargetType = targetPlayer Then

x = GetPlayerX(target)

y = GetPlayerY(target)

Else

x = MapNpc(MapNum).Npc(target).x

y = MapNpc(MapNum).Npc(target).y

End If

If Not isInRange(Range, GetPlayerX(Index), GetPlayerY(Index), x, y) Then

PlayerMsg Index, "Target not in range.", BrightRed

SendClearSpellBuffer Index

Exit Sub

End If

```

and add this **under** it:

```

If Not isPathCleared(Index, GetPlayerX(Index), GetPlayerY(Index), x, y) Then

PlayerMsg Index, "Can not reach target.", BrightRed

SendClearSpellBuffer Index

Exit Sub

End If

```
Link to comment
Share on other sites

> Ain't the ability to cause damage if the person is behind something the biggest plus point of magic?

No, i hate that thing in EO ![:D](http://www.touchofdeathforums.com/community/public/style_emoticons/<#EMO_DIR#>/biggrin.png)
Link to comment
Share on other sites

Magic in games is usually used in other games (including ranged) to hit people from spots where they cant hit you. Take Runescape for example.
Link to comment
Share on other sites

I think a more usesful system is changing how spells work. Make it so you cast it and click where it is on the map, that adds aim to the game. That'd be a little more useful than this, although, this adds a realistic point of view. If you do that, you can mash my idea with this and it would be a pretty sweet spell system.
Link to comment
Share on other sites

  • 6 months later...
Added one more feature to the script: It appears only CASTING [NAME OF MAGIC]! if you can hit the magic. Otherwise it will be ignored avoiding spam on the screen.

ModCombat ~ ServerSide

Search for:

```

If HasBuffered Then
        SendAnimation mapNum, Spell(spellnum).CastAnim, 0, 0, TARGET_TYPE_PLAYER, Index
```

An add this under it:

```

If isPathCleared(Index, GetPlayerX(Index), GetPlayerY(Index), x, y) Then
```
Search for:

```

If HasBuffered Then
        SendAnimation mapNum, Spell(spellnum).CastAnim, 0, 0, TARGET_TYPE_PLAYER, Index
```
An add it above this:

```

If targetType = TARGET_TYPE_PLAYER Then
        x = GetPlayerX(target)
        y = GetPlayerY(target)
        Else
        x = MapNpc(mapNum).Npc(target).x
        y = MapNpc(mapNum).Npc(target).y
        End If
```
Search for:

```

Function BufferSpell(ByVal Index As Long, ByVal spellslot As Long)
```
After

```

Dim targetType As Byte
Dim target As Long
```

Add it:

```

Dim x As Long
Dim y As Long
```

Search for:

```

TempPlayer(Index).SpellCD(spellslot) = GetTickCount + (Spell(spellnum).CDTime * 1000)
Call SendCooldown(Index, spellslot)
```
An under it add:

```

If isPathCleared(Index, GetPlayerX(Index), GetPlayerY(Index), x, y) Then
```
After:

```

SendActionMsg mapNum, Trim$(Spell(spellnum).Name) & "!", BrightRed, ACTIONMSG_SCROLL, GetPlayerX(Index) * 32, GetPlayerY(Index) * 32
```
An Add under it:

```

End if
```
Link to comment
Share on other sites

  • 2 months later...
This code works just fine, but there are some instances where I get a subscript out of range error here:

```
' Check new square
If CurX = x2 And CurY = y2 Then
Exit Do
' ======
ElseIf Map(GetPlayerMap(index)).Tile(CurX, CurY).Type = TILE_TYPE_BLOCKED Or Map(GetPlayerMap(index)).Tile(CurX, CurY).Type = TILE_TYPE_RESOURCE Then
' ElseIf Blocked(CurX, CurY) Then
' /=====
isPathCleared = False
Exit Function
End If
Loop
End If
isPathCleared = True

End Function

```
On this line:

```
ElseIf Map(GetPlayerMap(index)).Tile(CurX, CurY).Type = TILE_TYPE_BLOCKED Or Map(GetPlayerMap(index)).Tile(CurX, CurY).Type = TILE_TYPE_RESOURCE Then

```
I've tried recreating the error and it seems to happen when an NPC moves into only horizontal or vertical range from the diagonal calculation.
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...