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

EO [Any Version] Damage w/ DOT Fix


SkywardRiver
 Share

Recommended Posts

Hey there!

So, as far as I know, this bug exists in every single Eclipse Engine to date. (Besides my own of course, hehe)

The issue lies in the reading of damage while a DOT is active on an NPC. If you're attacking while a DOT is active, the damage will not be read. I can't quite remember why, as I made this fix quite a while ago, but it doesn't haha.

I had previously released this fix for EVB and the IndieRising community exclusively because of the former management of this place pissed me off from time to time, but I'll be posting it here now because of the change in ownership :D

Before we dive into the fix, know that if there are any errors, it's cause I'm pulling the fix straight out of my Engine. I'm trying to take out any extra stuff that I have that may cause errors, but I may miss something. Just know that I offer full support for any and all tutorials I release and if you find a bug, just post below and I'll help you fix it :D

Alright, this is all Server Sided:

First of all, add this to modCombat:

>! ```
Public Sub PlayerAttackNpcDOT(ByVal attacker As Long, ByVal MapNpcNum As Long, ByVal Damage As Long, Optional ByVal SpellNum As Long, Optional ByVal overTime As Boolean = False)
Dim Name As String
Dim exp As Long
Dim n As Long
Dim i As Long
Dim STR As Long
Dim Def As Long
Dim mapnum As Long
Dim NPCNum As Long
Dim buffer As clsBuffer
>! ' Check for subscript out of range
If IsPlaying(attacker) = False Or MapNpcNum <= 0 Or MapNpcNum > MAX_MAP_NPCS Or Damage < 0 Then
Exit Sub
End If
>! mapnum = GetPlayerMap(attacker)
NPCNum = MapNpc(mapnum).NPC(MapNpcNum).num
Name = Trim$(NPC(NPCNum).Name)

' set the regen timer
TempPlayer(attacker).stopRegen = True
TempPlayer(attacker).stopRegenTimer = GetTickCount

If Damage > 0 Then
>! ' Check for a weapon and say damage
SendActionMsg mapnum, "-" & Damage, BrightRed, 1, (MapNpc(mapnum).NPC(MapNpcNum).x * 32), (MapNpc(mapnum).NPC(MapNpcNum).y * 32)
SendBlood GetPlayerMap(attacker), MapNpc(mapnum).NPC(MapNpcNum).x, MapNpc(mapnum).NPC(MapNpcNum).y

If Damage >= MapNpc(mapnum).NPC(MapNpcNum).Vital(Vitals.HP) Then

' Calculate exp to give attacker
exp = NPC(NPCNum).exp
>! ' Make sure we dont get less then 0
If exp < 0 Then
exp = 1
End If
>! ' in party?
If TempPlayer(attacker).inParty > 0 Then
' pass through party sharing function
Party_ShareExp TempPlayer(attacker).inParty, exp, attacker, GetPlayerMap(attacker)
Else
' no party - keep exp for self
GivePlayerEXP attacker, exp
End If

'Drop the goods if they get it
For n = 1 To MAX_NPC_DROPS
If NPC(NPCNum).DropItem(n) = 0 Then Exit For

If Rnd <= NPC(NPCNum).DropChance(n) Then
Call SpawnItem(NPC(NPCNum).DropItem(n), NPC(NPCNum).DropItemValue(n), mapnum, MapNpc(mapnum).NPC(MapNpcNum).x, MapNpc(mapnum).NPC(MapNpcNum).y)
End If
Next

' Now set HP to 0 so we know to actually kill them in the server loop (this prevents subscript out of range)
MapNpc(mapnum).NPC(MapNpcNum).num = 0
MapNpc(mapnum).NPC(MapNpcNum).SpawnWait = GetTickCount
MapNpc(mapnum).NPC(MapNpcNum).Vital(Vitals.HP) = 0
UpdateMapBlock mapnum, MapNpc(mapnum).NPC(MapNpcNum).x, MapNpc(mapnum).NPC(MapNpcNum).y, False

' clear DoTs and HoTs
For i = 1 To MAX_DOTS
With MapNpc(mapnum).NPC(MapNpcNum).DoT(i)
.Spell = 0
.Timer = 0
.Caster = 0
.StartTime = 0
.Used = False
End With

With MapNpc(mapnum).NPC(MapNpcNum).HoT(i)
.Spell = 0
.Timer = 0
.Caster = 0
.StartTime = 0
.Used = False
End With
Next

Call CheckTasks(attacker, QUEST_TYPE_GOSLAY, NPCNum)

' send death to the map
Set buffer = New clsBuffer
buffer.WriteLong SNpcDead
buffer.WriteLong MapNpcNum
SendDataToMap mapnum, buffer.ToArray()
Set buffer = Nothing

'Loop through entire map and purge NPC from targets
For i = 1 To Player_HighIndex
If IsPlaying(i) And IsConnected(i) Then
If Player(i).Map = mapnum Then
If TempPlayer(i).targetType = TARGET_TYPE_NPC Then
If TempPlayer(i).Target = MapNpcNum Then
TempPlayer(i).Target = 0
TempPlayer(i).targetType = TARGET_TYPE_NONE
SendTarget i
End If
End If
End If
End If
Next
Else
' NPC not dead, just do the damage
MapNpc(mapnum).NPC(MapNpcNum).Vital(Vitals.HP) = MapNpc(mapnum).NPC(MapNpcNum).Vital(Vitals.HP) - Damage
>! ' Now check for guard ai and if so have all onmap guards come after'm
If NPC(MapNpc(mapnum).NPC(MapNpcNum).num).Behaviour = NPC_BEHAVIOUR_GUARD Then
For i = 1 To MAX_MAP_NPCS
If MapNpc(mapnum).NPC(i).num = MapNpc(mapnum).NPC(MapNpcNum).num Then
MapNpc(mapnum).NPC(i).Target = attacker
MapNpc(mapnum).NPC(i).targetType = 1 ' player
End If
Next
End If

' set the regen timer
MapNpc(mapnum).NPC(MapNpcNum).stopRegen = True
MapNpc(mapnum).NPC(MapNpcNum).stopRegenTimer = GetTickCount

End If

SendMapNpcVitals mapnum, MapNpcNum
End If
End Sub
>! ```
>!  
>! Now, in modCombat -> HandleDOT_Npc find this:
>! ```
PlayerAttackNpc .Caster, index, Vital, , True
>! ```
and replace it with this:
>! ```
PlayerAttackNpcDOT .Caster, index, Vital, , True
>! ```
 And I'm fairly sure that's it!
>!  
>! Now to explain what this does:
>!  
>! Instead of using the same function for damage as a normal attack, DoTs will now be calculated using a separate function. This allows for both types of damage to be read at the same time.
>!  
>! Now, this should work, but if you encounter any bugs while adding this tutorial feel free to post below and I'll help you out :D
>!  
>! ~SkywardRiver
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...