The following warnings occurred:
Warning [2] Use of undefined constant SAPI_NAME - assumed 'SAPI_NAME' (this will throw an Error in a future version of PHP) - Line: 3388 - File: inc/functions.php PHP 7.4.33-nmm7 (Linux)
File Line Function
/inc/functions.php 3388 errorHandler->error
/showthread.php 116 build_archive_link
Warning [2] Use of undefined constant IN_ARCHIVE - assumed 'IN_ARCHIVE' (this will throw an Error in a future version of PHP) - Line: 3331 - File: inc/functions.php PHP 7.4.33-nmm7 (Linux)
File Line Function
/inc/functions.php 3331 errorHandler->error
/inc/functions.php 3324 build_forum_breadcrumb
/showthread.php 195 build_forum_breadcrumb
Warning [2] Use of undefined constant IN_ARCHIVE - assumed 'IN_ARCHIVE' (this will throw an Error in a future version of PHP) - Line: 3331 - File: inc/functions.php PHP 7.4.33-nmm7 (Linux)
File Line Function
/inc/functions.php 3331 errorHandler->error
/showthread.php 195 build_forum_breadcrumb






Post Reply 
 
Thread Rating:
  • 0 Votes - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
Problem with custom spells...
Author Message
admin phoenix
Master
**

Posts: 354
Likes Given: 1
Likes Received: 23 in 13 posts
Joined: Mar 2012
Reputation: 3



Post: #11
RE: Problem with custom spells...
this code has to be in the file sphere_backward_compatibility.scp
cause there is also an function called npccast that doesn´t work.
thanks for this one!
05-04-2012 08:56 PM
Find all posts by this user Like Post Quote this message in a reply
Anarch Cassius
Master
**

Posts: 273
Likes Given: 19
Likes Received: 10 in 9 posts
Joined: Mar 2012
Reputation: 2



Post: #12
RE: Problem with custom spells...
Here's one with a few changes:
Better comments
Returns 0 if the spell can't be cast
RUNES function commented out but explained and included

EDIT: I have a 3rd function I use to determine if the spell is in skill range. I use this outside NPCCAST beforehand in the AI to see if it's even an option before it runs the mana test and sets the spell.

For now I put it in the main function. You can remove this part if you want to use NPCCANCAST like I do. The mana check should always stay in NPCCAST; the game will fizzle an NPC that tries to cast above skill and although it deducts mana it doesn't actually ensure there is enough allowing them cast at 0 mana without it.

A simple example of using CANCAST in AI:
Code:
[FUNCTION npccast_sorcery_offense]
    IF (<I.UID> == <OBJ.UID>)
        return 0
    ENDIF
    IF  (<npccancast s_summon_chaos_daemon>) && !(<R4>) && !(<FLAGS>&statf_conjured)
        npccast s_summon_chaos_daemon,<obj>
        return 1
    ELIF (<npccancast s_detonation>) && (<attacker> > 1) && !(<R3>)
        npccast s_detonation,<obj>
        return 1
    ELIF (<npccancast s_summon_djinn>) && !(<R3>) && !(<FLAGS>&statf_conjured)
        npccast s_summon_djinn,<obj>
        return 1
    ELIF (<npccancast s_summon_efreet>) && !(<R3>) && !(<FLAGS>&statf_conjured)
        npccast s_summon_efreet,<obj>
        return 1
    ELIF (<npccancast s_summon_hellhound>) && !(<R3>) && !(<FLAGS>&statf_conjured)
        npccast s_summon_hellhound,<obj>
        return 1
    ELIF (<npccancast s_fire_bolt>)
        npccast s_fire_bolt,<obj>
        return 1
    ENDIF
return 0
If goes down this list finding the first spell that isn't too difficult to cast and isn't randomly selected against or innapproriate to the situation. So they favor the most powerful spell the can cast but random selection keeps it interesting.

(Appropriate here means not using AoE against one target and not letting summons cast summons because that's just plain wrong)

I'm still working on the system. I should probably adjust this to look for a new spell if npccast returns 0 (not enough mana) but I don't want to overwhelm people.


The major functions

Code:
[FUNCTION npccast]
// Determine spell and skill used to cast
LOCAL.SPELL = <EVAL <ARGV[0]> &~ 0ff000000>
LOCAL.SKILL = <EVAL (<STREAT <SERV.SPELL.<LOCAL.SPELL>.SKILLREQ>>) &~ 0ff000000>
IF (<SERV.SPELL.<LOCAL.SPELL>.MANAUSE> > <MANA>)
    RETURN 0
ENDIF

//You can remove this if you use NPCCANCAST to check first
IF (<FVAL <STRARG <SERV.SPELL.<LOCAL.SPELL>.SKILLREQ>>+50> > <I.<SERV.SKILL.<LOCAL.SKILL>.KEY>>)
    RETURN 0
ENDIF

//Uncomment the following lines if you want NPCs to say WoP, you'll need the RUNES function
//IF (<EVAL STRLEN(<SERV.SPELL(<LOCAL.SPELL>).RUNES>)> > 0)
//     SAY <RUNES <LOCAL.SPELL>>
//ENDIF

//If we didn't get a valid skill, default to Magery
IF !(<LOCAL.SKILL>)
  LOCAL.SKILL = 25
ENDIF
// This is part of my casting management, you may also find it useful in systems
TAG.LASTCASTING=<eval (<SERV.TIME>+<SERV.SPELL.<LOCAL.SPELL>.CAST_TIME>)>
TAG.SPELLCASTING=<LOCAL.SPELL>

// Set spell target
IF (<ARGV> > 2) //use coords if given
    ACT = 0
    ACTP = <ARGV[1]>, <ARGV[2]>, <ARGV[3]>, <ARGV[4]>
ELIF (<SERV.SPELL.<LOCAL.SPELL>.FLAGS> & spellflag_targ_xyz) //use coords for ground targ spells regardless
    ACTP = <ACT.P>
    ACT = 0
ELSE
    REF1 = <ARGV[1]>
    IF !(<REF1.UID>)
        REF1 = <ACT.UID>
        IF !(<REF1.UID>)
            REF1 = <UID>
        ENDIF
    ENDIF
    ACT = <REF1.UID>
    ACTP = <REF1.P>
ENDIF

    
// Set character action
ACTPRV = <UID>
ACTARG1 = <LOCAL.SPELL>
ACTION = <LOCAL.SKILL>
RETURN 1

This function returns the WoP for a given spell. I use this in my custom spellbooks and for NPC casting.

Code:
[Function RUNES]
LOCAL.LENGTH = <EVAL STRLEN(<SERV.SPELL(<args>).RUNES>)>
LOCAL.CURRUNE=0
local.RUNESTRING="0"
WHILE (<eval <LOCAL.CURRUNE>> <= <eval <LOCAL.LENGTH>>)
    IF (strmatch(*0*,<LOCAL.runestring>))
    IF (strmatch(A,<STRSUB <eval <LOCAL.CURRUNE>> 1 <SERV.SPELL(<args>).RUNES>>))
        local.RUNESTRING="An "
    ELSEIF (strmatch(B,<STRSUB <eval <LOCAL.CURRUNE>> 1 <SERV.SPELL(<args>).RUNES>>))
        local.RUNESTRING="Bet "
    ELSEIF (strmatch(C,<STRSUB <eval <LOCAL.CURRUNE>> 1 <SERV.SPELL(<args>).RUNES>>))
        local.RUNESTRING="Corp "
    ELSEIF (strmatch(D,<STRSUB <eval <LOCAL.CURRUNE>> 1 <SERV.SPELL(<args>).RUNES>>))
        local.RUNESTRING="Des "
    ELSEIF (strmatch(E,<STRSUB <eval <LOCAL.CURRUNE>> 1 <SERV.SPELL(<args>).RUNES>>))
        local.RUNESTRING="Ex "
    ELSEIF (strmatch(F,<STRSUB <eval <LOCAL.CURRUNE>> 1 <SERV.SPELL(<args>).RUNES>>))
        local.RUNESTRING="Flam "
    ELSEIF (strmatch(G,<STRSUB <eval <LOCAL.CURRUNE>> 1 <SERV.SPELL(<args>).RUNES>>))
        local.RUNESTRING="Grav "
    ELSEIF (strmatch(H,<STRSUB <eval <LOCAL.CURRUNE>> 1 <SERV.SPELL(<args>).RUNES>>))
        local.RUNESTRING="Hur "
    ELSEIF (strmatch(I,<STRSUB <eval <LOCAL.CURRUNE>> 1 <SERV.SPELL(<args>).RUNES>>))
        local.RUNESTRING="In "
    ELSEIF (strmatch(J,<STRSUB <eval <LOCAL.CURRUNE>> 1 <SERV.SPELL(<args>).RUNES>>))
        local.RUNESTRING="Jux "
    ELSEIF (strmatch(K,<STRSUB <eval <LOCAL.CURRUNE>> 1 <SERV.SPELL(<args>).RUNES>>))
        local.RUNESTRING="Kal "
    ELSEIF (strmatch(L,<STRSUB <eval <LOCAL.CURRUNE>> 1 <SERV.SPELL(<args>).RUNES>>))
        local.RUNESTRING="Lor "
    ELSEIF (strmatch(M,<STRSUB <eval <LOCAL.CURRUNE>> 1 <SERV.SPELL(<args>).RUNES>>))
        local.RUNESTRING="Mani "
    ELSEIF (strmatch(N,<STRSUB <eval <LOCAL.CURRUNE>> 1 <SERV.SPELL(<args>).RUNES>>))
        local.RUNESTRING="Nox "
    ELSEIF (strmatch(O,<STRSUB <eval <LOCAL.CURRUNE>> 1 <SERV.SPELL(<args>).RUNES>>))
        local.RUNESTRING="Ort "
    ELSEIF (strmatch(P,<STRSUB <eval <LOCAL.CURRUNE>> 1 <SERV.SPELL(<args>).RUNES>>))
        local.RUNESTRING="Por "
    ELSEIF (strmatch(Q,<STRSUB <eval <LOCAL.CURRUNE>> 1 <SERV.SPELL(<args>).RUNES>>))
        local.RUNESTRING="Quas "
    ELSEIF (strmatch(R,<STRSUB <eval <LOCAL.CURRUNE>> 1 <SERV.SPELL(<args>).RUNES>>))
        local.RUNESTRING="Rel "
    ELSEIF (strmatch(S,<STRSUB <eval <LOCAL.CURRUNE>> 1 <SERV.SPELL(<args>).RUNES>>))
        local.RUNESTRING="Sanct "
    ELSEIF (strmatch(T,<STRSUB <eval <LOCAL.CURRUNE>> 1 <SERV.SPELL(<args>).RUNES>>))
        local.RUNESTRING="Tym "
    ELSEIF (strmatch(U,<STRSUB <eval <LOCAL.CURRUNE>> 1 <SERV.SPELL(<args>).RUNES>>))
        local.RUNESTRING="Uus "
    ELSEIF (strmatch(V,<STRSUB <eval <LOCAL.CURRUNE>> 1 <SERV.SPELL(<args>).RUNES>>))
        local.RUNESTRING="Vas "
    ELSEIF (strmatch(W,<STRSUB <eval <LOCAL.CURRUNE>> 1 <SERV.SPELL(<args>).RUNES>>))
        local.RUNESTRING="Wis "
    ELSEIF (strmatch(X,<STRSUB <eval <LOCAL.CURRUNE>> 1 <SERV.SPELL(<args>).RUNES>>))
        local.RUNESTRING="Xen "
    ELSEIF (strmatch(Y,<STRSUB <eval <LOCAL.CURRUNE>> 1 <SERV.SPELL(<args>).RUNES>>))
        local.RUNESTRING="Ylem "
    ELSEIF (strmatch(Z,<STRSUB <eval <LOCAL.CURRUNE>> 1 <SERV.SPELL(<args>).RUNES>>))
        local.RUNESTRING="Zu "
    ENDIF
    ELSE
    IF (strmatch(A,<STRSUB <eval <LOCAL.CURRUNE>> 1 <SERV.SPELL(<args>).RUNES>>))
        local.RUNESTRING="<local.RUNESTRING>An "
    ELSEIF (strmatch(B,<STRSUB <eval <LOCAL.CURRUNE>> 1 <SERV.SPELL(<args>).RUNES>>))
        local.RUNESTRING="<local.RUNESTRING>Bet "
    ELSEIF (strmatch(C,<STRSUB <eval <LOCAL.CURRUNE>> 1 <SERV.SPELL(<args>).RUNES>>))
        local.RUNESTRING="<local.RUNESTRING>Corp "
    ELSEIF (strmatch(D,<STRSUB <eval <LOCAL.CURRUNE>> 1 <SERV.SPELL(<args>).RUNES>>))
        local.RUNESTRING="<local.RUNESTRING>Des "
    ELSEIF (strmatch(E,<STRSUB <eval <LOCAL.CURRUNE>> 1 <SERV.SPELL(<args>).RUNES>>))
        local.RUNESTRING="<local.RUNESTRING>Ex "
    ELSEIF (strmatch(F,<STRSUB <eval <LOCAL.CURRUNE>> 1 <SERV.SPELL(<args>).RUNES>>))
        local.RUNESTRING="<local.RUNESTRING>Flam "
    ELSEIF (strmatch(G,<STRSUB <eval <LOCAL.CURRUNE>> 1 <SERV.SPELL(<args>).RUNES>>))
        local.RUNESTRING="<local.RUNESTRING>Grav "
    ELSEIF (strmatch(H,<STRSUB <eval <LOCAL.CURRUNE>> 1 <SERV.SPELL(<args>).RUNES>>))
        local.RUNESTRING="<local.RUNESTRING>Hur "
    ELSEIF (strmatch(I,<STRSUB <eval <LOCAL.CURRUNE>> 1 <SERV.SPELL(<args>).RUNES>>))
        local.RUNESTRING="<local.RUNESTRING>In "
    ELSEIF (strmatch(J,<STRSUB <eval <LOCAL.CURRUNE>> 1 <SERV.SPELL(<args>).RUNES>>))
        local.RUNESTRING="<local.RUNESTRING>Jux "
    ELSEIF (strmatch(K,<STRSUB <eval <LOCAL.CURRUNE>> 1 <SERV.SPELL(<args>).RUNES>>))
        local.RUNESTRING="<local.RUNESTRING>Kal "
    ELSEIF (strmatch(L,<STRSUB <eval <LOCAL.CURRUNE>> 1 <SERV.SPELL(<args>).RUNES>>))
        local.RUNESTRING="<local.RUNESTRING>Lor "
    ELSEIF (strmatch(M,<STRSUB <eval <LOCAL.CURRUNE>> 1 <SERV.SPELL(<args>).RUNES>>))
        local.RUNESTRING="<local.RUNESTRING>Mani "
    ELSEIF (strmatch(N,<STRSUB <eval <LOCAL.CURRUNE>> 1 <SERV.SPELL(<args>).RUNES>>))
        local.RUNESTRING="<local.RUNESTRING>Nox "
    ELSEIF (strmatch(O,<STRSUB <eval <LOCAL.CURRUNE>> 1 <SERV.SPELL(<args>).RUNES>>))
        local.RUNESTRING="<local.RUNESTRING>Ort "
    ELSEIF (strmatch(P,<STRSUB <eval <LOCAL.CURRUNE>> 1 <SERV.SPELL(<args>).RUNES>>))
        local.RUNESTRING="<local.RUNESTRING>Por "
    ELSEIF (strmatch(Q,<STRSUB <eval <LOCAL.CURRUNE>> 1 <SERV.SPELL(<args>).RUNES>>))
        local.RUNESTRING="<local.RUNESTRING>Quas "
    ELSEIF (strmatch(R,<STRSUB <eval <LOCAL.CURRUNE>> 1 <SERV.SPELL(<args>).RUNES>>))
        local.RUNESTRING="<local.RUNESTRING>Rel "
    ELSEIF (strmatch(S,<STRSUB <eval <LOCAL.CURRUNE>> 1 <SERV.SPELL(<args>).RUNES>>))
        local.RUNESTRING="<local.RUNESTRING>Sanct "
    ELSEIF (strmatch(T,<STRSUB <eval <LOCAL.CURRUNE>> 1 <SERV.SPELL(<args>).RUNES>>))
        local.RUNESTRING="<local.RUNESTRING>Tym "
    ELSEIF (strmatch(U,<STRSUB <eval <LOCAL.CURRUNE>> 1 <SERV.SPELL(<args>).RUNES>>))
        local.RUNESTRING="<local.RUNESTRING>Uus "
    ELSEIF (strmatch(V,<STRSUB <eval <LOCAL.CURRUNE>> 1 <SERV.SPELL(<args>).RUNES>>))
        local.RUNESTRING="<local.RUNESTRING>Vas "
    ELSEIF (strmatch(W,<STRSUB <eval <LOCAL.CURRUNE>> 1 <SERV.SPELL(<args>).RUNES>>))
        local.RUNESTRING="<local.RUNESTRING>Wis "
    ELSEIF (strmatch(X,<STRSUB <eval <LOCAL.CURRUNE>> 1 <SERV.SPELL(<args>).RUNES>>))
        local.RUNESTRING="<local.RUNESTRING>Xen "
    ELSEIF (strmatch(Y,<STRSUB <eval <LOCAL.CURRUNE>> 1 <SERV.SPELL(<args>).RUNES>>))
        local.RUNESTRING="<local.RUNESTRING>Ylem "
    ELSEIF (strmatch(Z,<STRSUB <eval <LOCAL.CURRUNE>> 1 <SERV.SPELL(<args>).RUNES>>))
        local.RUNESTRING="<local.RUNESTRING>Zu "
    ENDIF
    ENDIF
    LOCAL.CURRUNE += 1
ENDWHILE
RETURN <local.RUNESTRING>

Code:
[FUNCTION npccancast]
LOCAL.SPELL = <EVAL <args>>
LOCAL.SKILL = <EVAL (<STREAT <SERV.SPELL.<LOCAL.SPELL>.SKILLREQ>>)>
IF !(<SERV.SPELL.<LOCAL.SPELL>.MANAUSE> > <MANA>) && !(<FVAL <STRARG <SERV.SPELL.<LOCAL.SPELL>.SKILLREQ>>+50> > <I.<SERV.SKILL.<LOCAL.SKILL>.KEY>>)
    RETURN 1
ELSE
    RETURN 0
ENDIF
(This post was last modified: 05-05-2012 06:58 AM by Anarch Cassius.)
05-05-2012 06:18 AM
Find all posts by this user Like Post Quote this message in a reply
Jonaleth
Apprentice
*

Posts: 42
Likes Given: 0
Likes Received: 1 in 1 posts
Joined: Apr 2012
Reputation: 0



Post: #13
RE: Problem with custom spells...
Thank you for all of your comments, that was very kind of you.
I will study your scripts and try to learn from them. Smile
05-13-2012 12:44 AM
Find all posts by this user Like Post Quote this message in a reply
admin phoenix
Master
**

Posts: 354
Likes Given: 1
Likes Received: 23 in 13 posts
Joined: Mar 2012
Reputation: 3



Post: #14
RE: Problem with custom spells...
and use the force Smile
05-14-2012 04:15 PM
Find all posts by this user Like Post Quote this message in a reply
Post Reply 


Forum Jump:


User(s) browsing this thread: 1 Guest(s)