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

[EO] NPC Spells v.2.0.0


DJMaxus
 Share

Recommended Posts

This is a tutorial for Eclipse Origins v.2 Beta. It will allow NPCs to cast spells as determined in the NPC Editor. This is based on my previous tutorial with a few edits and improvements here and there. Hopefully, this will help you further your project.

**Notes**

*** Now Works with v.2.0.0**

*** Note: AoE Spells have not been tested, but are still included.**

*** If you have an NPC that has an animation already, the NPC's animation will show with the spell animation. I'll look into this later.**

_**How It Works:**_

A NPC will have a number of spells as determined in the NPC Editor and a max number as determined in the source. A NPC will cast spells on a player if the player is in the Spell's range and only after the casting time of the spell. If the spell is a healing spell, the NPC will heal itself. An NPC will only use a healing spell after it's HP has dropped to 30% or lower. A NPC can only heal itself a certain amount of times based on how high it's intelligence is. The damage and vital effect of an NPC is also dependent on the NPC's intelligence. The higher the intelligence of the NPC, the more effective it is with spells. AoE spells will hit all players on the map within the area of effect. All healing AoE spells will heal all NPCs on the map within the area of effect. An NPC can cast multiple spells, but must respect the Cooldown and cast times of each individual spell. An NPC can attack and cast spells simultaneously.

_**The Code:**_

==============

**Server Side**

==============

In **modConstants**

Find:

```
Public Const MAX_PARTY_MEMBERS As Long = 4
```

Underneath it, add:

```
' NPC Spells

Public Const MAX_NPC_SPELLS As Long = 5
```
*** This is the max amount of spells an NPC can have.**

In **modTypes**

Find : **Private Type NpcRec**

Add this to the bottom of **Private Type NpcRec** (before **End Type**)

```
' Npc Spells

Spell(1 To MAX_NPC_SPELLS) As Long
```

Find : **Private Type MapNpcRec**

Add this to the bottom of **Private Type MapNpcRec** (before **End Type**)

```
' Npc spells

SpellTimer(1 To MAX_NPC_SPELLS) As Long

Heals As Integer
```

In **modGameLogic**

Find : **Sub NpcAttackPlayer**

Below the entire sub, add this:

```
Sub NpcSpellPlayer(ByVal MapNpcNum As Long, ByVal Victim As Long, SpellSlotNum As Long)

Dim mapnum As Long

Dim i As Long

Dim n As Long

Dim SpellNum As Long

Dim Buffer As clsBuffer

Dim InitDamage As Long

Dim Damage As Long

Dim MaxHeals As Long

' 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

If SpellSlotNum <= 0 Or SpellSlotNum > MAX_NPC_SPELLS Then Exit Sub

' The Variables

mapnum = GetPlayerMap(Victim)

SpellNum = Npc(MapNpc(mapnum).Npc(MapNpcNum).Num).Spell(SpellSlotNum)

' Send this packet so they can see the person attacking

Set Buffer = New clsBuffer

Buffer.WriteLong SNpcAttack

Buffer.WriteLong MapNpcNum

SendDataToMap mapnum, Buffer.ToArray()

Set Buffer = Nothing

' CoolDown Time

If MapNpc(mapnum).Npc(MapNpcNum).SpellTimer(SpellSlotNum) > GetTickCount Then Exit Sub

' Spell Types

Select Case Spell(SpellNum).Type

' AOE Healing Spells

Case SPELL_TYPE_HEALHP

' Make sure an npc waits for the spell to cooldown

MaxHeals = 1 + Npc(MapNpc(mapnum).Npc(MapNpcNum).Num).Stat(Stats.intelligence) \ 25

If MapNpc(mapnum).Npc(MapNpcNum).Heals >= MaxHeals Then Exit Sub

If MapNpc(mapnum).Npc(MapNpcNum).Vital(Vitals.HP) <= Npc(MapNpc(mapnum).Npc(MapNpcNum).Num).HP * 0.3 Then

If Spell(SpellNum).IsAoE Then

For i = 1 To MAX_MAP_NPCS

If MapNpc(mapnum).Npc(i).Num > 0 Then

If MapNpc(mapnum).Npc(i).Vital(Vitals.HP) > 0 Then

If isInRange(Spell(SpellNum).AoE, MapNpc(mapnum).Npc(MapNpcNum).x, MapNpc(mapnum).Npc(MapNpcNum).y, MapNpc(mapnum).Npc(i).x, MapNpc(mapnum).Npc(i).y) Then

InitDamage = Spell(SpellNum).Vital + (Npc(MapNpc(mapnum).Npc(MapNpcNum).Num).Stat(Stats.intelligence) / 2)

MapNpc(mapnum).Npc(i).Vital(Vitals.HP) = MapNpc(mapnum).Npc(i).Vital(Vitals.HP) + InitDamage

SendActionMsg mapnum, "+" & InitDamage, BrightGreen, 1, (MapNpc(mapnum).Npc(i).x * 32), (MapNpc(mapnum).Npc(i).y * 32)

Call SendAnimation(mapnum, Spell(SpellNum).SpellAnim, 0, 0, TARGET_TYPE_NPC, MapNpcNum)

If MapNpc(mapnum).Npc(i).Vital(Vitals.HP) > Npc(MapNpc(mapnum).Npc(i).Num).HP Then

MapNpc(mapnum).Npc(i).Vital(Vitals.HP) = Npc(MapNpc(mapnum).Npc(i).Num).HP

End If

MapNpc(mapnum).Npc(MapNpcNum).Heals = MapNpc(mapnum).Npc(MapNpcNum).Heals + 1

MapNpc(mapnum).Npc(MapNpcNum).SpellTimer(SpellSlotNum) = GetTickCount + Spell(SpellNum).CDTime * 1000

Exit Sub

End If

End If

End If

Next

Else

' Non AOE Healing Spells

InitDamage = Spell(SpellNum).Vital + (Npc(MapNpc(mapnum).Npc(MapNpcNum).Num).Stat(Stats.intelligence) / 2)

MapNpc(mapnum).Npc(MapNpcNum).Vital(Vitals.HP) = MapNpc(mapnum).Npc(MapNpcNum).Vital(Vitals.HP) + InitDamage

SendActionMsg mapnum, "+" & InitDamage, BrightGreen, 1, (MapNpc(mapnum).Npc(MapNpcNum).x * 32), (MapNpc(mapnum).Npc(MapNpcNum).y * 32)

Call SendAnimation(mapnum, Spell(SpellNum).SpellAnim, 0, 0, TARGET_TYPE_NPC, MapNpcNum)

If MapNpc(mapnum).Npc(MapNpcNum).Vital(Vitals.HP) > Npc(MapNpc(mapnum).Npc(MapNpcNum).Num).HP Then

MapNpc(mapnum).Npc(MapNpcNum).Vital(Vitals.HP) = Npc(MapNpc(mapnum).Npc(MapNpcNum).Num).HP

End If

MapNpc(mapnum).Npc(MapNpcNum).Heals = MapNpc(mapnum).Npc(MapNpcNum).Heals + 1

MapNpc(mapnum).Npc(MapNpcNum).SpellTimer(SpellSlotNum) = GetTickCount + Spell(SpellNum).CDTime * 1000

Exit Sub

End If

End If

' AOE Damaging Spells

Case SPELL_TYPE_DAMAGEHP

' Make sure an npc waits for the spell to cooldown

If Spell(SpellNum).IsAoE Then

For i = 1 To Player_HighIndex

If IsPlaying(i) Then

If GetPlayerMap(i) = mapnum Then

If isInRange(Spell(SpellNum).AoE, MapNpc(mapnum).Npc(MapNpcNum).x, MapNpc(mapnum).Npc(MapNpcNum).y, GetPlayerX(i), GetPlayerY(i)) Then

InitDamage = Spell(SpellNum).Vital + (Npc(MapNpc(mapnum).Npc(MapNpcNum).Num).Stat(Stats.intelligence) / 2)

Damage = InitDamage - Player(i).Stat(Stats.willpower)

If Damage <= 0 Then

SendActionMsg GetPlayerMap(i), "RESIST!", Pink, 1, (GetPlayerX(i) * 32), (GetPlayerY(i) * 32)

Exit Sub

Else

NpcAttackPlayer MapNpcNum, i, Damage

SendAnimation mapnum, Spell(SpellNum).SpellAnim, 0, 0, TARGET_TYPE_PLAYER, MapNpcNum

MapNpc(mapnum).Npc(MapNpcNum).SpellTimer(SpellSlotNum) = GetTickCount + Spell(SpellNum).CDTime * 1000

Exit Sub

End If

End If

End If

End If

Next

' Non AoE Damaging Spells

Else

If isInRange(Spell(SpellNum).Range, MapNpc(mapnum).Npc(MapNpcNum).x, MapNpc(mapnum).Npc(MapNpcNum).y, GetPlayerX(Victim), GetPlayerY(Victim)) Then

InitDamage = Spell(SpellNum).Vital + (Npc(MapNpc(mapnum).Npc(MapNpcNum).Num).Stat(Stats.intelligence) / 2)

Damage = InitDamage - Player(Victim).Stat(Stats.willpower)

If Damage <= 0 Then

SendActionMsg GetPlayerMap(Victim), "RESIST!", Pink, 1, (GetPlayerX(Victim) * 32), (GetPlayerY(Victim) * 32)

Exit Sub

Else

NpcAttackPlayer MapNpcNum, Victim, Damage

SendAnimation mapnum, Spell(SpellNum).SpellAnim, 0, 0, TARGET_TYPE_PLAYER, Victim

MapNpc(mapnum).Npc(MapNpcNum).SpellTimer(SpellSlotNum) = GetTickCount + Spell(SpellNum).CDTime * 1000

Exit Sub

End If

End If

End If

End Select

End Sub
```

In **modServerLoop**

Find these three lines:

```
Else

' lol no npc combat ![:(](http://www.touchofdeathforums.com/community/public/style_emoticons/<#EMO_DIR#>/sad.png)

End If
```

And delete them.

Find this:

```
' ////////////////////////////////////////////

' // This is used for regenerating NPC's HP //

' ////////////////////////////////////////////
```

Above, add this:

```
' Spell Casting

For i = 1 To MAX_NPC_SPELLS

If Npc(npcNum).Spell(i) > 0 Then

If MapNpc(mapnum).Npc(x).SpellTimer(i) + (Spell(Npc(npcNum).Spell(i)).CastTime * 1000) < GetTickCount Then

NpcSpellPlayer x, target, i

End If

End If

Next

End If
```

Client Side

In **modTypes**

Find : **Private Type NpcRec**

Add this to the bottom of **Private Type NpcRec** (before **End Type**)

```
' Npc Spells

Spell(1 To MAX_NPC_SPELLS) As Long
```

In **modGameEditors**

Find: **Public Sub NpcEditorInit**

Find this line:

```
.txtDamage.text = Npc(EditorIndex).Damage
```

Underneath it, add:

```
.scrlSpellNum.Max = MAX_NPC_SPELLS

.scrlSpellNum.Value = 1
```

**_Form Work:_**

I've included an frmEditor_NPC that you can use and copy from.

That's should be all. Congrats, NPCs will now cast spells. Look through the code and modify it to your liking, I encourage you to do so. Have fun with the tutorial folks.
Link to comment
Share on other sites

  • Replies 188
  • Created
  • Last Reply

Top Posters In This Topic

Find this piece of code I posted above:
```
                            ' Are they in range?  if so GET'M!
                            If DistanceX <= n And DistanceY <= n Then
                                If Npc(NpcNum).Stat(Stats.intelligence) > 0 Then
                                    If Npc(NpcNum).Spell1 > 0 Or Npc(NpcNum).Spell2 > 0 Then
                                        If Spell(Npc(NpcNum).Spell1).Type = SPELL_TYPE_DAMAGEHP Or Spell(Npc(NpcNum).Spell2).Type = SPELL_TYPE_HEALHP Then
                                            Call NpcSpellPlayer(x, Target)
                                        End If
                                    End If
                                End If
                            End If
```
And replace it with:
```
                            ' Are they in range?  if so GET'M!
                            If DistanceX <= n And DistanceY <= n Then
                                If Npc(NpcNum).Stat(Stats.intelligence) > 0 Then
                                    If Npc(NpcNum).Spell1 > 0 Or Npc(NpcNum).Spell2 > 0 Then
                                            Call NpcSpellPlayer(x, Target)
                                        End If
                                    End If
                                End If
```
* This has been added to the original post.
Link to comment
Share on other sites

  • 1 month later...
@Im_Mad_1337:

> When I compile the client, I get
> ```
> Compile error:
> Ambiguous name detected: scrlSpell2_Change
> ```:/

That just means you have multiple scrlSpell2_Change subs in your code. Find and delete the other one(s) to make sure there is only one of these subs in your entire game.
Link to comment
Share on other sites

@DJMaxus:

> That just means you have multiple scrlSpell2_Change subs in your code. Find and delete the other one(s) to make sure there is only one of these subs in your entire game.

Thanks, but I doubt I did any of the "frmEditor_NPC" correctly, I'm very new to this, and just guessed what most of it meant XD
Link to comment
Share on other sites

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