Critical Magic Code

  • Lunar Engine v0.2.6 is out now! Download and check it out here. The map editor is also now fixed!

Raklen

Member
Member
Jan 27, 2014
15
0
0
Gold
0
#1
EDIT: i fall out and saw that the npc-damage formula doesn't count monster protection, now it's fixed

Heya, the promised is debt, for new mirage users i'll post a function that able spells to be critical (from 100 to 150% damage):

ALL SERVER SIDE

Under Function CanPlayerCriticalHit add this code (can modify it)

Code:
Function CanPlayerCriticalSpell(ByVal Index As Long) As Boolean
Dim i As Long, n As Long

    CanPlayerCriticalSpell = False
    
    'if the player has more than 0 magic he can do critical damage
    If GetPlayerMAGI(Index) > 0 Then
        n = Int(Rnd * 2)
        If n = 1 Then
            'the i means the chance of critical magic
            i = Int(GetPlayerMAGI(Index) / 6) + Int(GetPlayerLevel(Index) / 5)
    
            n = Int(Rnd * 100) + 1
            If n <= i Then
                CanPlayerCriticalSpell = True
            End If
        End If
    End If
End Function[/spoiler]

Now in Sub CastSpell we will have to modify some things, if you only want do critical damage with subHP spells u only will have to modify 2 sections (subHP to npcs and to players), i added critical heal too:

Player target Cast Spell:

[spoiler]If Player(Index).TargetType = TARGET_TYPE_PLAYER Then
        If IsPlaying(n) Then
            If GetPlayerHP(n) > 0 And GetPlayerMap(Index) = GetPlayerMap(n) And GetPlayerLevel(Index) >= 10 And GetPlayerLevel(n) >= 10 And Map(GetPlayerMap(Index)).Moral = MAP_MORAL_NONE And GetPlayerAccess(Index) <= 0 And GetPlayerAccess(n) <= 0 Then
'                If GetPlayerLevel(n) + 5 >= GetPlayerLevel(Index) Then
'                    If GetPlayerLevel(n) - 5 <= GetPlayerLevel(Index) Then
                        'Call MapMsg(GetPlayerMap(Index), GetPlayerName(Index) & " casts " & Trim(Spell(SpellNum).Name) & " on " & GetPlayerName(n) & ".", BrightBlue)
                
                        Select Case Spell(SpellNum).Type
                            Case SPELL_TYPE_SUBHP
                            Damage = (Int(GetPlayerMAGI(Index) / 4) + Spell(SpellNum).Data1) + (Rnd * 5) - 2 - GetPlayerProtection(n)
                            If Not CanPlayerCriticalSpell(Index) Then
                                Damage = (Int(GetPlayerMAGI(Index) / 4) + Spell(SpellNum).Data1) + (Rnd * 5) - 2
                            Else
                            h = (Int(GetPlayerMAGI(Index) / 4) + Spell(SpellNum).Data1) + (Rnd * 5) - 2
                            Damage = h + Int(Rnd * Int(h / 2)) + 5 - GetPlayerProtection(n)
                            Call PlayerMsg(Index, "You feel your magic gets out of control doing a savage damage!", BrightCyan)
                            Call PlayerMsg(i, GetPlayerName(Index) & " blasts you with a enormous might!", BrightCyan)
                            End If
                                
                                If Damage > 0 Then
                                    Call SpellAttackPlayer(Index, n, Damage)
                                Else
                                    Call PlayerMsg(Index, "The spell was to weak to hurt " & GetPlayerName(n) & "!", BrightRed)
                                End If
                    
                            Case SPELL_TYPE_SUBMP
                                Call SetPlayerMP(n, GetPlayerMP(n) - Spell(SpellNum).Data1)
                                Call SendMP(n)
                
                            Case SPELL_TYPE_SUBSP
                                Call SetPlayerSP(n, GetPlayerSP(n) - Spell(SpellNum).Data1)
                                Call SendSP(n)
                        End Select
'                    Else
'                        Call PlayerMsg(Index, GetPlayerName(n) & " is far to powerful to even consider attacking.", BrightBlue)
'                    End If
'                Else
'                    Call PlayerMsg(Index, GetPlayerName(n) & " is to weak to even bother with.", BrightBlue)
'                End If
            
                ' Take away the mana points
                Call SetPlayerMP(Index, GetPlayerMP(Index) - MPReq)
                Call SendMP(Index)
                Casted = True
            Else
                If GetPlayerMap(Index) = GetPlayerMap(n) And Spell(SpellNum).Type >= SPELL_TYPE_ADDHP And Spell(SpellNum).Type <= SPELL_TYPE_ADDSP Then
                    Select Case Spell(SpellNum).Type
                    
                        Case SPELL_TYPE_ADDHP
                            'Call MapMsg(GetPlayerMap(Index), GetPlayerName(Index) & " casts " & Trim(Spell(SpellNum).Name) & " on " & GetPlayerName(n) & ".", BrightGreen)
                            
                            If Not CanPlayerCriticalSpell(Index) Then
                            Heal = (Int(GetPlayerMAGI(Index) / 4) + Spell(SpellNum).Data1) + (Rnd * 5) - 2
                            Else
                            h = (Int(GetPlayerMAGI(Index) / 4) + Spell(SpellNum).Data1) + (Rnd * 5) - 2
                            Heal = h + Int(Rnd * Int(n / 2)) + 5
                            Call PlayerMsg(Index, "You feel a strange feeling that boost your healing!", BrightCyan)
                            Call PlayerMsg(i, GetPlayerName(Index) & " heal you with a extreme power!", BrightCyan)
                            Call SetPlayerHP(n, GetPlayerHP(n) + Heal)
                            
                            Call SendHP(n)
                            End If
                                    
                        Case SPELL_TYPE_ADDMP
                            'Call MapMsg(GetPlayerMap(Index), GetPlayerName(Index) & " casts " & Trim(Spell(SpellNum).Name) & " on " & GetPlayerName(n) & ".", BrightBlue)
                            
                            Heal = (Int(GetPlayerMAGI(Index) / 4) + Spell(SpellNum).Data1) + (Rnd * 5) - 2
                            
                            Call SetPlayerMP(n, GetPlayerMP(n) + Heal)
                            Call SendMP(n)
                    
                        Case SPELL_TYPE_ADDSP
                            'Call MapMsg(GetPlayerMap(Index), GetPlayerName(Index) & " casts " & Trim(Spell(SpellNum).Name) & " on " & GetPlayerName(n) & ".", BrightBlue)
                            Call SetPlayerMP(n, GetPlayerSP(n) + (Rnd * 5) - 2 + Spell(SpellNum).Data1)
                            Call SendMP(n)
                    End Select
Now go to the section of NPC target spell and replace the things u need:

Code:
If Npc(MapNpc(GetPlayerMap(Index), n).Num).Behavior <> NPC_BEHAVIOR_FRIENDLY And Npc(MapNpc(GetPlayerMap(Index), n).Num).Behavior <> NPC_BEHAVIOR_SHOPKEEPER Then
            'Call MapMsg(GetPlayerMap(Index), GetPlayerName(Index) & " casts " & Trim(Spell(SpellNum).Name) & " on a " & Trim(Npc(MapNpc(GetPlayerMap(Index), n).Num).Name) & ".", BrightBlue)
            
            Select Case Spell(SpellNum).Type
                Case SPELL_TYPE_ADDHP
                    MapNpc(GetPlayerMap(Index), n).HP = MapNpc(GetPlayerMap(Index), n).HP + Spell(SpellNum).Data1
                
                Case SPELL_TYPE_SUBHP
                    
                            If Not CanPlayerCriticalSpell(Index) Then
                                Damage = (Int(GetPlayerMAGI(Index) / 4) + Spell(SpellNum).Data1) + (Rnd * 5) - 2 - Int(Npc(MapNpc(GetPlayerMap(Index), n).Num).DEF / 2)
                            Else
                            h = (Int(GetPlayerMAGI(Index) / 4) + Spell(SpellNum).Data1) + (Rnd * 5) - 2
                            Damage = h + Int(Rnd * Int(h / 2)) + 5 - Int(Npc(MapNpc(GetPlayerMap(Index), n).Num).DEF / 2)
                            Call PlayerMsg(Index, "You feel your magic gets out of control doing a savage damage!", BrightCyan)
                            End If
                    If Damage > 0 Then
                        Call SpellAttackNPC(Index, n, Damage)
                    Else
                        Call PlayerMsg(Index, "The spell was to weak to hurt " & Trim(Npc(MapNpc(GetPlayerMap(Index), n).Num).Name) & "!", BrightRed)
                    End If
                    
                Case SPELL_TYPE_ADDMP
                    MapNpc(GetPlayerMap(Index), n).MP = MapNpc(GetPlayerMap(Index), n).MP + Spell(SpellNum).Data1
                
                Case SPELL_TYPE_SUBMP
                    MapNpc(GetPlayerMap(Index), n).MP = MapNpc(GetPlayerMap(Index), n).MP - Spell(SpellNum).Data1
            
                Case SPELL_TYPE_ADDSP
                    MapNpc(GetPlayerMap(Index), n).SP = MapNpc(GetPlayerMap(Index), n).SP + Spell(SpellNum).Data1
                
                Case SPELL_TYPE_SUBSP
                    MapNpc(GetPlayerMap(Index), n).SP = MapNpc(GetPlayerMap(Index), n).SP - Spell(SpellNum).Data1
            End Select
The next step (if this doesnt work) i'll post it here down, cause i dont know the characters limit of the posts.
 

Raklen

Member
Member
Jan 27, 2014
15
0
0
Gold
0
#2
EDIT: I think the first part works fine without the second, but i have too much double-code and i must do this, i will optimize my server when i have more knowledge about vb6 :p

Okk, this second step have two things, one is a fix of spell casting with a weapon worn, and the other is a fix if the first part doesnt work, add those 2 subs, the original subs spellatacks credits goes to his owner, i only modified some values and added kingdom cases to change start_map players.

You can put this under Sub NpcAttack:
Code:
Sub SpellAttackNPC(ByVal Attacker As Long, ByVal MapNpcNum As Long, ByVal Damage As Long)
Dim Name As String
Dim Exp As String
Dim n As Long, i As Long
Dim STR As Long, DEF As Long, MapNum As Long, NpcNum As Long

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, MapNpcNum).Num
Name = Trim(Npc(NpcNum).Name)

Call SendDataToMapBut(Attacker, GetPlayerMap(Attacker), "ATTACK" & SEP_CHAR & Attacker & SEP_CHAR & END_CHAR)

If Damage >= MapNpc(MapNum, MapNpcNum).HP Then
Call PlayerMsg(Attacker, "You cast on a " & Name & " for " & Damage & " hit points, killing it.", BrightRed)

STR = Npc(NpcNum).STR
DEF = Npc(NpcNum).DEF
Exp = STR * DEF * 2



If Exp < 0 Then
Exp = 1
End If

If Player(Attacker).InParty = NO Then
Call SetPlayerExp(Attacker, GetPlayerExp(Attacker) + Exp)
Call PlayerMsg(Attacker, "You have gained " & Exp & " experience points.", BrightBlue)
Else
Exp = Exp / 1.5

If Exp < 0 Then
Exp = 1
End If

Call SetPlayerExp(Attacker, GetPlayerExp(Attacker) + Exp)
Call PlayerMsg(Attacker, "You have gained " & Exp & " party experience points.", BrightBlue)

n = Player(Attacker).PartyPlayer
If n > 0 Then
Call SetPlayerExp(n, GetPlayerExp(n) + Exp)
Call PlayerMsg(n, "You have gained " & Exp & " party experience points.", BrightBlue)
End If
End If

n = Int(Rnd * Npc(NpcNum).DropChance) + 1
If n = 1 Then
Call SpawnItem(Npc(NpcNum).DropItem, Npc(NpcNum).DropItemValue, MapNum, MapNpc(MapNum, MapNpcNum).x, MapNpc(MapNum, MapNpcNum).y)
End If

MapNpc(MapNum, MapNpcNum).Num = 0
MapNpc(MapNum, MapNpcNum).SpawnWait = GetTickCount
MapNpc(MapNum, MapNpcNum).HP = 0

Call SendDataToMap(MapNum, "NPCDEAD" & SEP_CHAR & MapNpcNum & SEP_CHAR & END_CHAR)

Call CheckPlayerLevelUp(Attacker)

If Player(Attacker).InParty = YES Then
Call CheckPlayerLevelUp(Player(Attacker).PartyPlayer)
End If

If Player(Attacker).TargetType = TARGET_TYPE_NPC And Player(Attacker).Target = MapNpcNum Then
Player(Attacker).Target = 0
Player(Attacker).TargetType = 0
End If
Else
MapNpc(MapNum, MapNpcNum).HP = MapNpc(MapNum, MapNpcNum).HP - Damage

Call PlayerMsg(Attacker, "You cast on a " & Name & " for " & Damage & " hit points.", White)

If MapNpc(MapNum, MapNpcNum).Target = 0 And MapNpc(MapNum, MapNpcNum).Target <> Attacker Then
If Trim(Npc(NpcNum).AttackSay) <> "" Then
Call PlayerMsg(Attacker, "A " & Trim(Npc(NpcNum).Name) & " says, '" & Trim(Npc(NpcNum).AttackSay) & "' to you.", SayColor)
End If
End If

MapNpc(MapNum, MapNpcNum).Target = Attacker

If Npc(MapNpc(MapNum, MapNpcNum).Num).Behavior = NPC_BEHAVIOR_GUARD Then
For i = 1 To MAX_MAP_NPCS
If MapNpc(MapNum, i).Num = MapNpc(MapNum, MapNpcNum).Num Then
MapNpc(MapNum, i).Target = Attacker
End If
Next i
End If
End If

Player(Attacker).AttackTimer = GetTickCount
End Sub
And this under the Sub SpellAttackNPC:
Code:
Sub SpellAttackPlayer(ByVal Attacker As Long, ByVal Victim As Long, ByVal Damage As Long)
Dim Exp As Long
Dim n As Long
Dim i As Long

If IsPlaying(Attacker) = False Or IsPlaying(Victim) = False Or Damage < 0 Then
Exit Sub
End If

Call SendDataToMapBut(Attacker, GetPlayerMap(Attacker), "ATTACK" & SEP_CHAR & Attacker & SEP_CHAR & END_CHAR)

If Damage >= GetPlayerHP(Victim) Then
Call SetPlayerHP(Victim, 0)

Call PlayerMsg(Attacker, "You cast on" & GetPlayerName(Victim) & " for " & Damage & " hit points.", White)
Call PlayerMsg(Victim, GetPlayerName(Attacker) & " casts on you for " & Damage & " hit points.", BrightRed)

Call GlobalMsg(GetPlayerName(Victim) & " has been killed by " & GetPlayerName(Attacker), BrightRed)

If GetPlayerWeaponSlot(Victim) > 0 Then
Call PlayerMapDropItem(Victim, GetPlayerWeaponSlot(Victim), 0)
End If
If GetPlayerArmorSlot(Victim) > 0 Then
Call PlayerMapDropItem(Victim, GetPlayerArmorSlot(Victim), 0)
End If
If GetPlayerHelmetSlot(Victim) > 0 Then
Call PlayerMapDropItem(Victim, GetPlayerHelmetSlot(Victim), 0)
End If
If GetPlayerShieldSlot(Victim) > 0 Then
Call PlayerMapDropItem(Victim, GetPlayerShieldSlot(Victim), 0)
End If

Exp = Int(GetPlayerExp(Victim) / 10)

If Exp < 0 Then
Exp = 0
End If

If Exp = 0 Then
Call PlayerMsg(Victim, "You lost no experience points.", BrightRed)
Call PlayerMsg(Attacker, "You received no experience points from that weak insignificant player.", BrightBlue)
Else
Call SetPlayerExp(Victim, GetPlayerExp(Victim) - Exp)
Call PlayerMsg(Victim, "You lost " & Exp & " experience points.", BrightRed)
Call SetPlayerExp(Attacker, GetPlayerExp(Attacker) + Exp)
Call PlayerMsg(Attacker, "You got " & Exp & " experience points for killing " & GetPlayerName(Victim) & ".", BrightBlue)
End If

If GetPlayerPK(Victim) = NO Then
            'this is my faction code, dont need to copy it
            'Select Case GetPlayerkingdom(Victim)
            'Case 1
            'Call PlayerWarp(Victim, 2, 4, 4)

            'Case 2
            Call PlayerWarp(Victim, 2, 8, 6)
               ' End Select
Else
Call PlayerWarp(Victim, 6, 6, 6)
        Call PlayerMsg(Victim, "You have died and paid the price of being a killer!", BrightRed)
        Call GlobalMsg(GetPlayerName(Victim) & " has died and paid the price of being a killer!", BrightRed)
End If

Call SetPlayerHP(Victim, GetPlayerMaxHP(Victim))
Call SetPlayerMP(Victim, GetPlayerMaxMP(Victim))
Call SetPlayerSP(Victim, GetPlayerMaxSP(Victim))
Call SendHP(Victim)
Call SendMP(Victim)
Call SendSP(Victim)

Call CheckPlayerLevelUp(Attacker)

If Player(Attacker).TargetType = TARGET_TYPE_PLAYER And Player(Attacker).Target = Victim Then
Player(Attacker).Target = 0
Player(Attacker).TargetType = 0
End If

If GetPlayerPK(Victim) = NO Then
If GetPlayerPK(Attacker) = NO Then
Call SetPlayerPK(Attacker, YES)
Call SendPlayerData(Attacker)
Call GlobalMsg(GetPlayerName(Attacker) & " has been deemed a Player Killer!", BrightRed)
End If
Else
Call SetPlayerPK(Victim, NO)
Call SendPlayerData(Victim)
Call GlobalMsg(GetPlayerName(Victim) & " has been bloody murdered and paid his crimes for being a Player Killer!!!", BrightRed)
End If
Else
Call SetPlayerHP(Victim, GetPlayerHP(Victim) - Damage)
Call SendHP(Victim)

Call PlayerMsg(Attacker, "You cast on " & GetPlayerName(Victim) & " for " & Damage & " hit points.", White)
Call PlayerMsg(Victim, GetPlayerName(Attacker) & " casts on you for " & Damage & " hit points.", BrightRed)
End If

Player(Attacker).AttackTimer = GetTickCount
End Sub
if i forgot something please be free to say it, we're here to learn and fix errors :)

See ya!