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

Making NPCs cast spells (Not final but works excellent)


Elenfir
 Share

Recommended Posts

Hey ya'll

I have the goal of rebuilding the NPC AI in Eclipse since they're abit stupid atm.
I've had some minor succes but still the edits lag the server too much.

This tutorial does not change the actual AI for the NPC, just gives them the ability to use Spells in melee or at a distance.
Altho if you have uber scriptingskills you could actually do something quite advanced with this.
But this is a quite simple way of creating spell casting NPCs.

UPSIDE: Well you get casting NPCs

DOWNSIDE: Requires quite alot of scripting. a tip is to use DG1423's spellscript and reverse it so that the dealer of DMG is the NPC instead of the player. And you also need to get the m,x,y of the attacking NPC for wall, ripple and homing spells.
Plus if you're not careful with the randomizer the NPC could actually cast 1 spell every second. It is fixiable tho with the use of timers or lower the chance that the NPC will cast (more on that further down in the tut).
Also this does not implement NPCmana, altho it is fixable by adding an MP scroll in the source and then make a function in the source that subtracts mana from the MapNpcNum.mana variable and sends a true or false value back to the Main.txt if the NPC has mana or not. But I'll leave that part to someone else to make a tutorial about ;)

Anyhow you should at least have a fair knowledge of scripting to make this work since this isn't a "full" tutorial.

Ok, you only need to add the following code in the Server part of the source:

In modGeneral:
Find:
```
' Check if the npc can attack the targeted player player
If Target > 0 Then
    ' Is the target playing on the same map?

```
Alter it so it looks like this:
```
' Check if the npc can attack the targeted player player
If Target > 0 Then
    MyScript.ExecuteStatement "Scripts\Main.txt", "OnNpcRound " & Target & "," & MapNPC(Y, X).num
    ' Is the target playing on the same map?

```
Now open you Main.txt and add the following code (anywhere outside a Sub)

```
Sub OnNpcRound(index, mapnpcnum)
        Call PlayerMsg(index, "OMG it's an NPC round!", RED)
End Sub

```
What the above does is that it runs the OnNpcRound sub every turn the Npc takes. But if you leave it at this it will call the playermessage as soon as any NPC in the game initiate combat with you. And that is no good now is it?

EDIT - > Only runs when combat between the NPC and PLAYER is initiated

So what is this useful for?

Well you could let's say make a folder named ummm, "mobs" in you server dir.
Let's say you want your Orc Shaman to have a 20% chance of casting a FireStrike at the player every round. Open the NPC list and find out what number your Shaman has.
ex. 4:Orc Shaman

**THE CODE BELOW IS NOT TESTED!!!!!!!**

Create an .ini file in your mobs folder named "4.ini"
In here you can place the variables that you want the mobcaster to have on theirspells. The example code below is just an example. But you could add submenus (1 per spell the caster have) to make them have more spells.
So you could add [ATKSPELL1] [ATKSPELL2] and so on. And in the [SPELLCASTING]
you could add a variable like "nratkspells=2" and "healingspell=1".
Then you could randomize with conditioners from the Script Sub which atk spell to cast and then make a condition to see if the NPC is low on health and when he is, he'll try to cast a healingspell if it's set to 1.
Example code:
```
[SPELLCASTING]
cancast=1
castchance=200
dmglow=10
dmghigh=20
animation=1
spellname=FireStrike

```
Now go back to your Main.txt and OnNpcRound and add something like this:

```
Sub OnNpcRound(index, mapnpcnum)
      CanCast = GetVar("mobs\" & mapnpcnum & ".ini", "SPELLCASTING", "cancast")
      If CanCast == 1 Then
        ChanceToCast = GetVar("mobs\" & mapnpcnum & ".ini", "SPELLCASTING", "castchance")
            RollForChance = rand(1,1000)
            If RollForChance < ChanceToCast Then
                CALL SUB FOR SPELL OR EQUAL HERE
                SpellName = GetVar("mobs\" & mapnpcnum & ".ini", "SPELLCASTING", "spellname")
                DMGLOW = GetVar("mobs\" & mapnpcnum & ".ini", "SPELLCASTING", "dmglow")
                DMGHIGH = GetVar("mobs\" & mapnpcnum & ".ini", "SPELLCASTING", "dmghigh")
                SpellDamage = rand(DMGLOW, DMGHIGH)
                AnimNr = GetVar("mobs\" & mapnpcnum & ".ini", "SPELLCASTING", "animation")
                Call PlayerMsg(index, "" & GetNpcName(mapnpcnum) & " hits you with a " & SpellName & " for " & SpellDamage & "!", BRIGHTRED)
                Call spellanim(AnimNr, GetPlayerMap(index), GetPlayerX(index), GetPlayerY(index))

            End If
      End If
End Sub

```
I'm not claiming that this is a final solution but I hope that maybe someone might find it useful :)

**AND ONCE AGAIN:**
The only thing tested by me is the Source and the Sub and that works perfectly.
If I end up using this for NPC casting I'll post a new tut with a better scripting part.
And if any of you master coders out there have comments or suggestions on how to change it, just add your comment below :)
Feel free to use but if you do, make sure to give me some creds ;)

If it seems unclear in anyway (which it probably does) just gimme a PM and I'll try to ellaborate.

I'm not a great writer, so I apologize if it feels "messy"…...

Cheers folks!

**EDIT:**

Below is a script that I've tried and it works great. Once again, no AI changes but does enable spellcasting. Just make sure to add a damageplayer or setplayerhp/sendhp to send the damage the spell does. The below does not use spelltypes or range. More on that once I've tested it properly.

THe below code checks if the NPC can cast spells. Every tick it checks against the castchance to see if the NPC will cast a spell that turn, then gets dmg modifiers and calculates if it is a critical hit. You need to setup the NPCNUM.ini with the variables you find in the script below, just PM or post here if you have questions or now a smoother way of solving it. VB or SadScript ain't exactly my main programming language so I'm sure there is a better solution then this :)
```
'Executes each round NPC takes while in combat
Sub OnNpcRound(index, mapnpcnum)
    CanCast = GetVar("mobs\casters\" & mapnpcnum & ".ini", "SPELLCASTING", "cancast")
    SpNr = GetVar("mobs\casters\" & mapnpcnum & ".ini", "SPELLCASTING", "numberspells")
    If CanCast = 1 Then
        If SpNr > 1 Then
            SpNr = rand(1,SpNr)
        End If 
    Call NPCMagic(Index, mapnpcnum, SpNr) 
    End If

End Sub

'Handles NPC spells
Sub NPCMagic(Index, mapnpcnum, spellno)
    Dim HRoll
    Dim HChance
    HRoll = rand(1,1000)
HChance = GetVar("mobs\casters\" & mapnpcnum & ".ini", "SPELL" & spellno, "castchance")

If HRoll < HChance Then
    SpellTxt = GetVar("mobs\casters\" & mapnpcnum & ".ini", "SPELL" & spellno, "spellpretxt")
    SpellName = GetVar("mobs\casters\" & mapnpcnum & ".ini", "SPELL" & spellno, "spellname")
        AnimateNR = GetVar("mobs\casters\" & mapnpcnum & ".ini", "SPELL" & spellno, "anim")
        DmgHigh = GetVar("mobs\casters\" & mapnpcnum & ".ini", "SPELL" & spellno, "dmghigh")
    DmgLow = GetVar("mobs\casters\" & mapnpcnum & ".ini", "SPELL" & spellno, "dmglow")
    CritAnim = GetVar("mobs\casters\" & mapnpcnum & ".ini", "SPELL" & spellno, "critanim")
    CritChance = GetVar("mobs\casters\" & mapnpcnum & ".ini", "SPELL" & spellno, "critchance")
    CritMod = GetVar("mobs\casters\" & mapnpcnum & ".ini", "SPELL" & spellno, "critmod")
        CritTxt = GetVar("mobs\casters\" & mapnpcnum & ".ini", "SPELL" & spellno, "critpretxt")
        CritRoll = rand(1,1000)
        If CritRoll < CritChance Then
            DmgDeal = DmgHigh * CritMod
            Call PlayerMsg(index, "" & GetNpcName(mapnpcnum) & " " & CritTxt & " " & SpellName & " dealing " & DmgDeal & " criticaldamage." , BRIGHTRED)
            Call spellanim(CritAnim, GetPlayerMap(index), GetPlayerX(index), GetPlayerY(index))
        Else
        DmgDeal = rand(DmgLow, DmgHigh)
        Call PlayerMsg(index, "" & GetNpcName(mapnpcnum) & " " & SpellTxt & " " & SpellName & " dealing " & DmgDeal & " damage." , RED)
            Call spellanim(AnimateNR, GetPlayerMap(index), GetPlayerX(index), GetPlayerY(index))
        End If
Else
    Exit Sub
    End If

End Sub

```
EDIT:

Been working on removing all the .ini edits for smoother and quicker creation. So far I've changed the NPC AI abit. Added an option and a textfield at NPC creation where you can choose if the NPC is Ranged or Melee. If you choose Melee the NPC will act as normal, if you choose ranged you need to set the textfield to a range which the NPC will try to stay from the character. So if you set the range to 5, every time the NPC moves it will try to stay 5 sq away from the Player it's attacking. The NPC casting sequence is now sourced aswell and all NPCspell info is saved in .dat files instead of .ini. I made the casting sequence in source mainly because it ended up taking alot of scripting space, plus that I found it easier to calculate range in source, couldn't get it to function properly in the sadscript.

Added this to the NPCeditor aswell to speed up creation. Everything works, just need a logic for elements and displaying animations. Will post the full source when this is done :) Also the NPC now have a mana setting. It reduces the NPC mana and everything, just need to blt out the NPC manabars. And I haven't fixed anything with blt yet so don't really know where to start. But I'm sure I'll get there eventually
![](http://www.sportson.se/site/files/NPCEditor 1.bmp)
Link to comment
Share on other sites

  • 2 weeks later...
Thanks!

Gotten abit further, still some loose ends. Going away for 2 weeks starting monday, but after that it shouldn't be long before I can post a full source. Also new Feature added. You can Now choose Ranged, MeleeBrave, MeleeWimp, Wimp and MeleeCaster as AI setting for the NPCs.

What the different additions do:
Ranged: Tries to keep the player at a range of X when combat is initiated.
MeleeBrave: Act as the normal NPCs do, try to get close and attack
MeleeWimp: Act as MeleeBrave except that the npc will switch behavior after reaching a certain % of their hitpoints. So let's say you set the wimpy at 10% and the NPC has 1000 HP. Once it reaches 100 or less in HP it will try to flee.
Wimp: Might not be useful but since I made the MeleeWimp it was a quite small edit. Once combat is initiated the Wimp NPC will try to flee no matter his condition.
MeleeCaster: Is a sort of mage and uses a mix of the ranged, MeleeBrave and MeleeWimp setting. They have 2 modifiers that controls their actions, Mana and HP. If the mana goes below X% he will switch to melee. But he also has the wimpy setting. So if he reaches  X% Hp he will try to flee. And I've also made a conditioner so that if the NPC is fleeing when he gets low on mana he will not switch behavior but keep fleeing.

I want to add RangedWimpy, working on that now and also adding the mana condition to the Ranged AI. Still abit unsure on how to handle it tho.

Still need to solve arrows for NPCs. But since I still haven't dared to dig into the blt commands I'm afraid this will take awhile.

All of the above is tested and work quite good. Still some minorbugs when they switch behavior and when they are resetting their targets. And I still need to add a setting for NPC movementspeed. But hopefully I'll have all of this fully working and bugfree in a month or so :)

Glad that you liked it. :)
Link to comment
Share on other sites

  • 1 month later...
The code in the first post works excellent.

I've just had alot to do at work lately so the additions to the NPC editor and sourced spellcasting aren't implemented yet.
But works well in scriptform. The only thing that this lacks is a range calculator but that is quite an easy fix.

If you can't solve the range calc then PM me and I can guide you through it.
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...