Author Topic: Calling a script from AngelScript  (Read 4382 times)

Offline wladimiiir

  • Rotator
  • Independent FOnline developer
Calling a script from AngelScript
« on: May 08, 2015, 12:28:32 am »
Let's say, I have string with the value of "myCoolModule@mySuperCoolFunction". Is there a way how to call the script function that is represented by this value?
I could not find any useful info that this could be done from AngelScript. The only way, which comes to my mind, is to call DLL with C++ function which would call the AngelScript function in return.

Any ideas? Thanks.

Offline Wipe

  • Rotator
  • Random is god
Re: Calling a script from AngelScript
« Reply #1 on: May 08, 2015, 01:30:24 am »
Not counting .dlls... hmm, let the workarounds flow~

Server-side you can use time events to run function, with zero delay. Of course, you can't get return value of the function then, plus you'll be limited to int[], uint[], and everything what can be bytepacked as arguments.
Client-side you can use RunServerScriptUnsafe() and pass your string - server's job is to call RunClientScript() using your string as function argument. Same limitations as above.

;D
Games are meant to be created, not played...

Offline wladimiiir

  • Rotator
  • Independent FOnline developer
Re: Calling a script from AngelScript
« Reply #2 on: May 08, 2015, 03:56:35 pm »
Yeah, I am aware of those options. :)

What I am trying to do is to call fix_ functions in fix_boy.fos, basically, as I am remaking the FixBoy on client side, calling my unsafe_fix functions on server side, which should try to call script functions defined in CraftItem.

So none of this can be used, because they use different arguments. :(

Offline Ghosthack

  • Rotator
  • Bytecruncher
Re: Calling a script from AngelScript
« Reply #3 on: May 08, 2015, 05:51:50 pm »
Sounds like you have to do a call to a wrapper function with a string argument which can then call the appropriate function, you're able to reduce the amount of boilerplate code by using macros for definitions and calls.

Offline Wipe

  • Rotator
  • Random is god
Re: Calling a script from AngelScript
« Reply #4 on: May 09, 2015, 05:54:28 am »
Got bored with own bugs, so why not create some for others :D

Code: [Select]
#define valid#(ptr) (@ptr!= null)

funcdef int fixFunc( Critter@ player, int state, CraftItem& craft );

class FixData
{
    string Name;
    private fixFunc@ func;

    FixData( string& name, fixFunc@ func )
    {
        this.Name = name;
        @this.func = func;
    }

    int Call( Critter@ player, int state, CraftItem& craft )
    {
        if( valid(func) )
            return( func( player, state, craft ));

        return( -1 ); // error mark
    }
};

array<FixData> Wrapper;

void InitFixboy()
{
    Wrapper.insertLast( FixData( "fix_silly", @fix_silly ));
    Wrapper.insertLast( FixData( "fix_dummy", @fix_dummy ));
}

int fix_silly( Critter@ player, int state, CraftItem& craft )
{
    return( 1207 );
}

int fix_dummy( Critter@ player, int state, CraftItem& craft )
{
    return( 1337 );
}

void unsafe_fix( Critter@ player, int craftItem, int state, int, string@ func, array<int>@ )
{
    int result = -1; // error mark

    if( valid(func) && func.length() > 0 )
    {
        for( uint w=0, wLen=Wrapper.length; w<wLen; w++ )
        {
            if( Wrapper[w].Name == func )
            {
                CraftItem@ craft = GetCraftItem( craftItem );
                if( valid(craft) )
                    result = Wrapper[w].Call( player, state, craft );

                break;
            }
        }
    }

    Log( "RESULT "+(valid(func)?func:"<invalid>")+":"+result );

    if( result == -1 )
    {
         // error handling
         return;
    }

    // further result processing
}

#ifdef __ASCOMPILER
void test()
{
    InitFixboy();

    unsafe_fix( null, 0, 0, 0, "fix_silly", null );
    unsafe_fix( null, 0, 0, 0, "fix_dummy", null );
    unsafe_fix( null, 0, 0, 0, "fix_incorrect", null );
    unsafe_fix( null, 0, 0, 0, null, null );
}
#endif

So yeah, pure AS example; hope it's clear enough for you.

All manual work left is to fill InitFixboy() with all of yours fix_ functions; sadly can't see a way to automate it. I also used Critter@ instead of Critter& for test purposes, so that one need fixing too. Can still be improved, for example by scrapping string@ func usage and relay on CraftItem::Script instead - again, it's done that way or ASCompiler would get mad.

As i understand you want to avoid .dlls [where whole thing would be much easier and shorter] for maximum portability, or is there any other reason?
Games are meant to be created, not played...

Offline wladimiiir

  • Rotator
  • Independent FOnline developer
Re: Calling a script from AngelScript
« Reply #5 on: May 09, 2015, 08:21:16 pm »
Thanks for your effort. You made a complex (and clean code) solution of what I have ended with: :)
Code: [Select]
#include "fix_boy.fos"
FixFunction@ GetFixFunction(string functionName)
{
if(functionName == "fix_boy@fix_AnyStuff")
return @fix_AnyStuff;
else if(functionName == "fix_boy@fix_AnyRounds")
return @fix_AnyRounds;
        // add your fix_ functions here
else
return null;
}
I would use your code, though, if you don't might. ;)

As i understand you want to avoid .dlls [where whole thing would be much easier and shorter] for maximum portability, or is there any other reason?
Not really, this is still an option, but for me a little more complicated with more effort to realize.

Re: Calling a script from AngelScript
« Reply #6 on: May 11, 2015, 09:32:45 pm »
Is there a real reason to stick with hard-coded CraftItem over a scripted craft system? Other than for production speed.

Offline wladimiiir

  • Rotator
  • Independent FOnline developer
Re: Calling a script from AngelScript
« Reply #7 on: May 13, 2015, 08:38:01 pm »
The only reason why I stick with the current one is that if someone would like to use this "advanced" FixBoy, he does not have to recreate all craft definitions from FOCRAFT.MSG to some different system.
But I have also noticed that 2238 had some endeavor for creating independent CraftItem definitions. :)