Mythruna
April 19, 2024, 01:59:52 AM *
Welcome, Guest. Please login or register.
Did you miss your activation email?

Login with username, password and session length
News: Welcome to the new forums. See "Announcements" for a note for new users.
 
   Home   Help Search Login Register  
Pages: [1]
  Print  
Author Topic: Scripting Tools  (Read 10990 times)
pspeed
Administrator
Hero Member
*****
Posts: 5612



View Profile
« on: October 30, 2011, 01:39:48 PM »

I'm sure we've all seen the Scripted Dialogs post on the Features forum, and if not... what are you still doing here silly, GO READ IT. The point is, I would really like to know how one of us could import our own scripts since I really wanna mess around with this. Groovy doesn't seem that confusing so I'm sure it can't be all that hard to learn, and would therefor I could try working with Mythruna and actually feel important since I don't know java. Cheesy Also paul if at all possible could I make a request for a modding tool of some sort that would allow us to use test npcs or something or am I asking for the moon here?

First, things aren't to the point where I can do a modding tool, I guess.  Such support is on my roadmap but things need to be in place, first.  For example, adding an NPC is not possible because none of the systems are there to support an NPC.

Regarding the scripting stuff, the API is not really documented except the few samples I've posted in the "setting up a server" page.  For servers, any *.init.groovy scripts in the ./scripts directory will be run when the server starts up.  They can use this opportunity to setup script hooks, etc.

There is similar support for single player scripts by putting scripts in ./mods/scripts

Dialog scripts can go in the ./mods/dialogs directory in single player and the ./dialogs directory for a server.  You'd have to have some other thing setup to launch a dialog, though.  For example, you could add a tool or something that when clicked could call dialogs.startDialog( player, "mydialog-withoutextension-or-path" )

The API that is available isn't really documented and is somewhat limited to the systems that I've needed so far.  I'll follow up with an example of the water repair tool I have as an admin, though.  Maybe that's helpful.
« Last Edit: November 01, 2011, 03:04:30 PM by pspeed » Logged
pspeed
Administrator
Hero Member
*****
Posts: 5612



View Profile
« Reply #1 on: October 30, 2011, 01:41:07 PM »

Here is my water repair tool.  It basically scans the 32x32x32 area around where the player clicks and looks for empty blocks with water next to them.

Code:
import mythruna.*;
import mythruna.es.*;
import mythruna.script.*;

import java.util.Random;

WATER = 7;
WATER_TOP = 8;

action( group:"Water Tools", name:"Repair Water", type:ActionType.Block ) {

    console.echo( "Repairing water at:" + it );

    loc = it.getBlock();   
    type = world.getType( loc.x, loc.y, loc.z, null );
 
    if( type != WATER && type != WATER_TOP ) {
        console.echo( "Must select a water block." );
    }
 
    // Iterate over the area around the selection and fix
    // neighboring water cells
    for( int z = loc.z - 16; z < loc.z + 16; z++ ) {
        console.echo( "Level:" + z );
        for( int x = loc.x - 16; x < loc.x + 16; x++ ) {
            for( int y = loc.y - 16; y < loc.y + 16; y++ ) {
                   
                type = world.getType( x, y, z, null );
                if( type != 0 ) {
                    continue;
                }
               
                // Check the four directions
                for( int d = 0; d < Direction.UP; d++ ) {
                    neighbor = world.getType( x + Direction.DIRS[d][0],
                                              y + Direction.DIRS[d][1],   
                                              z + Direction.DIRS[d][2],
                                              null );
                    if( neighbor == WATER_TOP ) {
                        world.setType( x, y, z, WATER_TOP, null );
                        break;
                    }
                   
                    if( neighbor == WATER ) {
                        world.setType( x, y, z, WATER, null );
                        break;
                    }                                             
                }
            }
        }
    }   
}

on( [playerJoined] ) {
    type, event ->

    println( "Adding water tools to player:" + player );

    def refs = []

    ToolActions existing = player[ToolActions.class];
 
    if( playerData != null ) {         
        if( playerData.get( "grant.water" ) != null ) {
            refs += actions.getRef( "Water Tools", "Repair Water" );
        }
    }           
   
    println "Refs:" + refs;
   
    player << new ToolActions(refs, existing)
}   
Logged
randomprofile
Global Moderator
Sr. Member
*****
Posts: 265


View Profile WWW
« Reply #2 on: October 30, 2011, 04:01:30 PM »

EEEEEEEK, another language D:, thanks for reply I suppose so if I inport my own script to the /mods/ folder for single player would I be able to run it using F1 too or...?

eeeh newbish question... where does is the mods folder locatated exactly because I cannot seem to find it D:
« Last Edit: October 30, 2011, 04:09:47 PM by SleeperCell #42 » Logged
pspeed
Administrator
Hero Member
*****
Posts: 5612



View Profile
« Reply #3 on: October 30, 2011, 04:19:29 PM »

It works pretty much just like the server init scripts.  In the easiest approach, you'd hook some code onto an event to add a tool to the tool scroller.  The water script I posted is an example.  It sets up some actions and attaches them to the tools for a player with the "water" grant... you could take out the if statement and just apply it all the time for single player.

Technically, you can hack in all kinds of stuff around the API... even making calls directly into the graphics layer, etc..  I don't encourage it, though. Smiley  It's easier to make some tools to do specific things.

I plan to some day support the "total conversion" concept as much as possible... but that's way down the line.
Logged
randomprofile
Global Moderator
Sr. Member
*****
Posts: 265


View Profile WWW
« Reply #4 on: October 31, 2011, 04:03:33 AM »

Wait so where do I put my scripts right now to make them work?
Logged
pspeed
Administrator
Hero Member
*****
Posts: 5612



View Profile
« Reply #5 on: October 31, 2011, 10:37:50 AM »

In single player?  Or are you running your own server?
Logged
randomprofile
Global Moderator
Sr. Member
*****
Posts: 265


View Profile WWW
« Reply #6 on: October 31, 2011, 11:51:54 AM »

Most likely single player since I don't feel like running a linux VM.
Logged
pspeed
Administrator
Hero Member
*****
Posts: 5612



View Profile
« Reply #7 on: October 31, 2011, 12:04:15 PM »

Most likely single player since I don't feel like running a linux VM.

You don't have to run the server from linux.  You just have to download the linux bundle... but that's only because in that version the code isn't tied up in an .exe file.  The public server is hosted on Windows, for example.

When you run the single player game it looks for directories relative to the current working directory.  Usually the same directory where the .exe file is.  This is also where it sticks the mythruna.db directory.  If you make a mods subdirectory next to your mythruna.db (not in it, sibling to it) and a scripts directory under that, you should be able to put some init.groovy scripts in there.

Try the water tool script above only change:
Code:
    if( playerData != null ) {          
        if( playerData.get( "grant.water" ) != null ) {
            refs += actions.getRef( "Water Tools", "Repair Water" );
        }
    }            

to:
Code:
    refs += actions.getRef( "Water Tools", "Repair Water" );

ie: remove the conditional part and make it always add the tooll.

If the client picks it up properly then you should end up with a "Repair Water" tool in your tool scroller.  This tool will fill in empty water spaces that are adjacent to other water.  So, for example, if you place a water block and click on it with that tool you will end up with a 32x32 slab of water.
Logged
randomprofile
Global Moderator
Sr. Member
*****
Posts: 265


View Profile WWW
« Reply #8 on: October 31, 2011, 04:06:39 PM »

Well... from what I just read... this is what I needed to do.

I've tried this and it works. I get no errors in the log, but I do not get the
Code:
println( "Adding water tools to player:" + player );
confirmation in chat D:. Any reason exactly?
But can we please call it something else besides groovy script... like mythscript or do we have to call it groovy script?

« Last Edit: October 31, 2011, 04:21:32 PM by SleeperCell #42 » Logged
pspeed
Administrator
Hero Member
*****
Posts: 5612



View Profile
« Reply #9 on: October 31, 2011, 05:38:46 PM »

Heheh... it's groovy so I call it groovy.  That way in syntax highlighting editors it shows up right without extra work.

You won't see printlns as they don't go to the player's chat... they go to nowhere when you run the .exe.  If you ran the jars from a command line then you'd see that output on the command line... which is true in the case of a server.  The windows .exe doesn't have a command line and anyway it hides this output.

The scripting environment is not great yet... and would be easier to debug if you ran from the command line with the linux version (on Windows).  Let me know if you want more information on how to do that.
Logged
randomprofile
Global Moderator
Sr. Member
*****
Posts: 265


View Profile WWW
« Reply #10 on: November 01, 2011, 05:22:18 AM »

That would be nice... also can I have a short list on the basic mythruna functions like on
Code:
( [playerJoined] )
And are we legally obligated to call it groovy?

~~~EDIT~~~
Also would it be hard to add a declaring function in mythruna, that would tell me what scripts were loaded or... does the Linux version do that?
« Last Edit: November 01, 2011, 08:28:21 AM by SleeperCell #42 » Logged
pspeed
Administrator
Hero Member
*****
Posts: 5612



View Profile
« Reply #11 on: November 01, 2011, 03:41:57 PM »

That would be nice... also can I have a short list on the basic mythruna functions like on
Code:
( [playerJoined] )

Let's call the Linux version the "command line version in Linux package form" just to avoid confusion. Smiley  If you download and unzip the linux version just like any other.  Open a command prompt, change to the directory where it's  installed and type:
Code:
java -XX:MaxDirectMemorySize=1024m -Xmx512m -jar Mythruna-20111017.jar

Note: you can also just copy the .sh file to a .cmd and remove the first line.

I'll have to follow up separately with details on the API.  I've only added what I needed so if something exists then some script file somewhere uses it... even if it's one of the scripts embedded inside the mythruna.jar.

Quickly, though... the on() function attaches the {} bit of script to one or more events.  There are various events like serverStarted, playerConnected, playerJoined, etc..  playerJoined and playerLeft are the only ones that work on both client and server.

so,
Code:
on( [playerConnected] ) {
    type, event ->

    // This code will be called whenever a player connects.  type is the event
    // type (always playerConnected in this case)
    // event is the event data.  Mostly you can ignore those.
    // There are some variables available in scripts like this such as
    // player - the player entity
    // connection - only on the server, this is the network connection of the player
    // playerData - only on the server right now, this is access to the data in the player's
    //                  player database record.  It has their stats, their characters (only one right now)
    //                  the grants they have, last position on logout, etc.
    // entities - access to the entity system
    // console - console.echo() will echo things to the player's chat console in single or multiplayer.
    // world - access to the world database
    // ...and more that I probably should document separately.
}

And note: many of those "things" above are only available in the event scripts, ie: the code inside the {} and not in the outer raw script where you see things like:
Code:
println '------ water commands version:$Revision: 1473 $';

The .init script is run when the server/client starts and it attaches the {} sections to events to get run later.  But at init time, obviously there is no player available, etc..

And are we legally obligated to call it groovy?

No.  But leaving a groovy extension makes syntax highlighting editors play nice.  Also, the scripting layer I use supports a variety of scripting languages (python, ruby, javascript, etc.) and I'd like to support them someday when I have time to better adapt the API to those languages (not worth doing until it's stable).  And in that case, the groovy extension will be really important.

I suppose I could call the groovy ones "mythscript" or whatever to denote them as the standard way but considering the huge groovy community and all the work that has gone into that, it feels slightly pretentious. Smiley

~~~EDIT~~~
Also would it be hard to add a declaring function in mythruna, that would tell me what scripts were loaded or... does the Linux version do that?

I think when you run from the command line it prints the scripts that it is loading.  Though you will also see printlns like above.

There is no way to get this list from within a script though it would be easy to add.
Logged
Pages: [1]
  Print  
 
Jump to:  

Powered by MySQL Powered by PHP Powered by SMF 1.1.20 | SMF © 2013, Simple Machines Valid XHTML 1.0! Valid CSS!