Shadow Trails Demo

Exhibition Shadow Trails 2017 - tech demo 3.0

No permission to download
Projects meant as a technical demonstrator or instructional tutorial.
What I do is the exact instructions as the 1st post, I can't test the shadow trails, it chrashes right after adding these 2 lines:

animationscript      data/scripts/scripts.c
ondrawscript      data/scripts/shadowon.c

Have you just added those two lines without putting the @cmd shawdow ... ... ?
 
If you do not mind send me a private link to your mod and I will add support for shadows this is odd as it should be a simple integration to any mod.
 
I'll release a new demo in a few days, it was supoused tobe ready last week but work stuff happened, so there, will do!
 
Hello!

I've loved using this script. However I faced a similar issue that Mr.Q did while trying to implement it into my latest project. Which is odd since I never had this issue with the shadow script prior.

The function "shadow" is not recognized according to the log, despite including both the animationscript and the ondrawscript. Anybody know of a solution to this?
 
I've loved using this script. However I faced a similar issue that Mr.Q did while trying to implement it into my latest project. Which is odd since I never had this issue with the shadow script prior.
That is weird, because I am using like I posted above and it works:

animationscript data/scripts/grabscript.c
ondrawscript data/scripts/shadowon.c

The shadow() function is inside my grabscript.c file (in fact, it redirects to another file which has it):

C-like:
//// ---------------------------------- SHADOWTRAIL - msmalik681
void shadow(int max, int delay, int timeout, int alpha, int tintm, int r, int g, int b)
{//animation script for shadow trails
    void self = getlocalvar("self"); //Get calling entity.
    int anim = getentityproperty(self, "animationid");//Get calling animation id.
    //if any values null set defaults
    if(max==NULL()){max=5;}
    if(delay==NULL()){delay=20;}
    if(timeout==NULL()){timeout=120;}
    if(alpha==NULL()){alpha=6;}
    if(tintm==NULL()){tintm=2;}
    if(r==NULL()){r=0;}
    if(g==NULL()){g=0;}
    if(b==NULL()){b=255;}
    //store all recorded data into entity variables.
    setentityvar(self,"shadow.anim", anim);
    setentityvar(self,"shadow.max", max);
    setentityvar(self,"shadow.delay", delay);
    setentityvar(self,"shadow.timeout", timeout);
    setentityvar(self,"shadow.alpha", alpha);
    setentityvar(self,"shadow.tintm", tintm);
    setentityvar(self,"shadow.r", r);
    setentityvar(self,"shadow.g", g);
    setentityvar(self,"shadow.b", b);
}

and my shadow script file (keep in mind that I use a fowarded, this is why you see actual_main() instead of main()

C-like:
//{max shadows} {delay between shadows} {shadow timeout} {alpha} {tintmode} {red} {green} {blue}
void actual_main()
{
    int i, j;
    void spr;
    int facing;
    float y, z, x;
    void self = getlocalvar("self"); //get caller
    int ani = getentityproperty(self, "animationid"); //current animation id
    int time = openborvariant("elapsed_time");    //current time in game
    int timer = getlocalvar("shadow."+self+".timer");    //hold a variable for timer
    //recover all properties recovered from animation script
    int max = getentityvar(self,"shadow.max");
    int delay = getentityvar(self,"shadow.delay");
    int timeout = getentityvar(self,"shadow.timeout");
    int alpha = getentityvar(self,"shadow.alpha");
    int tintm = getentityvar(self,"shadow.tintm");
    int r = getentityvar(self,"shadow.r");
    int g = getentityvar(self,"shadow.g");
    int b = getentityvar(self,"shadow.b");
    int anim = getentityvar(self,"shadow.anim");
    if(timer==NULL()){setlocalvar("shadow."+self+".timer",-1);}    //if timer has no value set timer -1
    void table = getentityproperty(self, "colourmap");


if(ani==anim && timer<time) //if the animation id from animation script matches current animation id and timer below 0
{
    spr = getentityproperty(self, "sprite");        //caller current sprite
    x = getentityproperty(self, "x");            //caller x position
    z = getentityproperty(self, "z");            //caller z position
    y = getentityproperty(self, "y");            //caller y position
    facing = !getentityproperty(self, "direction");        //caller facing direction


//settextobj(0,55, 200,3,9999999999,"working");
//drawsprite(spr,openborvariant("xpos")+x,z-y-openborvariant("ypos")-10,z,50);


    for(i=1; i<=max; i++) //find an empty shadow slot and store cuurent sprite with other details
        {
            if(getlocalvar("shadow."+self+"."+i+".s")==NULL())
             {
                setlocalvar("shadow."+self+"."+i+".s", spr);
                setlocalvar("shadow."+self+"."+i+".x", x);
                setlocalvar("shadow."+self+"."+i+".z", z);
                setlocalvar("shadow."+self+"."+i+".y", y);
                setlocalvar("shadow."+self+"."+i+".f", facing);
                setlocalvar("shadow."+self+"."+i+".tm", tintm);
                setlocalvar("shadow."+self+"."+i+".a", alpha);
                setlocalvar("shadow."+self+"."+i+".r", r);
                setlocalvar("shadow."+self+"."+i+".g", g);
                setlocalvar("shadow."+self+"."+i+".b", b);
                setlocalvar("shadow."+self+"."+i+".t", openborvariant("elapsed_time")+timeout);
                setlocalvar("shadow."+self+".timer",openborvariant("elapsed_time")+delay);    //set a delay before next sprite can be recorded
                break; //stop the loop
             }
        }
}


        for(j=1; j<=max; j++)//show any stored shadows or if their time is up remove them
         {
          if(getlocalvar("shadow."+self+"."+j+".t")!=NULL())
          {
            if (getlocalvar("shadow."+self+"."+j+".t")<openborvariant("elapsed_time"))
            {
            setlocalvar("shadow."+self+"."+j+".s", NULL());
            setlocalvar("shadow."+self+"."+j+".x", NULL());
            setlocalvar("shadow."+self+"."+j+".z", NULL());
            setlocalvar("shadow."+self+"."+j+".y", NULL());
            setlocalvar("shadow."+self+"."+j+".f", NULL());
            setlocalvar("shadow."+self+"."+j+".c", NULL());
            setlocalvar("shadow."+self+"."+j+".t", NULL());
            setlocalvar("shadow."+self+"."+j+".tm", NULL());
            setlocalvar("shadow."+self+"."+j+".a", NULL());
            setlocalvar("shadow."+self+"."+j+".r", NULL());
            setlocalvar("shadow."+self+"."+j+".g", NULL());
            setlocalvar("shadow."+self+"."+j+".b", NULL());
            } else    {
                changedrawmethod(NULL(),"reset",1);
                changedrawmethod(NULL(), "table", table);
                changedrawmethod(NULL(),"flipx",getlocalvar("shadow."+self+"."+j+".f")); //face same as caller
                changedrawmethod(NULL(),"alpha",getlocalvar("shadow."+self+"."+j+".a")); //apply alpha effect
                changedrawmethod(NULL(),"tintmode",getlocalvar("shadow."+self+"."+j+".tm")); //apply tint effect
                changedrawmethod(NULL(),"tintcolor",rgbcolor(getlocalvar("shadow."+self+"."+j+".r"),getlocalvar("shadow."+self+"."+j+".g"),getlocalvar("shadow."+self+"."+j+".b"))); //set a tint
                drawsprite(getlocalvar("shadow."+self+"."+j+".s"),getlocalvar("shadow."+self+"."+j+".x")-openborvariant("xpos"),getlocalvar("shadow."+self+"."+j+".z")-getlocalvar("shadow."+self+"."+j+".y")-openborvariant("ypos")-4,getlocalvar("shadow."+self+"."+j+".z")-j);
                changedrawmethod(NULL(),"reset",1);
                }
          }
         }
}

Usage:
@cmd shadow 5 10 30 6 2 0 0 155
You can see they working here:
 
The shadow.c and the shadowon.c are exactly what's in the demo files.

As for the scripts.c file, that may be, if I had to assume, where my problem could like since that's what's different. I'm working with a lot of script files so this is what I have got:
Code:
#import "data/scripts/shadow.c"
#import "data/scripts/script.c"
#import "data/scripts/shadowon.c"
#import "data/scripts/randsound.c"
#import "data/scripts/spawns.c"
#import "data/scripts/spawn06.c"
#import "data/scripts/spawnentity.c"
#import "data/scripts/3DAttack.c"
#import "data/scripts/superarmor.c"
#import "data/scripts/enemyX.c"
#import "data/scripts/atks.c"
#import "data/scripts/on_movement.c"
#import "data/scripts/run.c"
#import "data/scripts/slowmo.c"
#import "data/scripts/script.c"
#import "data/scripts/grabscript.c"
#import "data/scripts/escript.c"

As for the command I would use, this is what I would put in an animation frame before it crashed: @cmd shadow 10 7 40 6 2 255 0 0
 
Try pasting this directly into the "scripts.c" file

C-like:
//// ---------------------------------- SHADOWTRAIL - msmalik681
void shadow(int max, int delay, int timeout, int alpha, int tintm, int r, int g, int b)
{//animation script for shadow trails
    void self = getlocalvar("self"); //Get calling entity.
    int anim = getentityproperty(self, "animationid");//Get calling animation id.
    //if any values null set defaults
    if(max==NULL()){max=5;}
    if(delay==NULL()){delay=20;}
    if(timeout==NULL()){timeout=120;}
    if(alpha==NULL()){alpha=6;}
    if(tintm==NULL()){tintm=2;}
    if(r==NULL()){r=0;}
    if(g==NULL()){g=0;}
    if(b==NULL()){b=255;}
    //store all recorded data into entity variables.
    setentityvar(self,"shadow.anim", anim);
    setentityvar(self,"shadow.max", max);
    setentityvar(self,"shadow.delay", delay);
    setentityvar(self,"shadow.timeout", timeout);
    setentityvar(self,"shadow.alpha", alpha);
    setentityvar(self,"shadow.tintm", tintm);
    setentityvar(self,"shadow.r", r);
    setentityvar(self,"shadow.g", g);
    setentityvar(self,"shadow.b", b);
}
 
Try pasting this directly into the "scripts.c" file

C-like:
//// ---------------------------------- SHADOWTRAIL - msmalik681
void shadow(int max, int delay, int timeout, int alpha, int tintm, int r, int g, int b)
{//animation script for shadow trails
    void self = getlocalvar("self"); //Get calling entity.
    int anim = getentityproperty(self, "animationid");//Get calling animation id.
    //if any values null set defaults
    if(max==NULL()){max=5;}
    if(delay==NULL()){delay=20;}
    if(timeout==NULL()){timeout=120;}
    if(alpha==NULL()){alpha=6;}
    if(tintm==NULL()){tintm=2;}
    if(r==NULL()){r=0;}
    if(g==NULL()){g=0;}
    if(b==NULL()){b=255;}
    //store all recorded data into entity variables.
    setentityvar(self,"shadow.anim", anim);
    setentityvar(self,"shadow.max", max);
    setentityvar(self,"shadow.delay", delay);
    setentityvar(self,"shadow.timeout", timeout);
    setentityvar(self,"shadow.alpha", alpha);
    setentityvar(self,"shadow.tintm", tintm);
    setentityvar(self,"shadow.r", r);
    setentityvar(self,"shadow.g", g);
    setentityvar(self,"shadow.b", b);
}

Just tried that, still no luck unfortunately, @O Ilusionista
 
Last edited:
Trails should gradually decrease opacity when they fade out, this does not happen here, how can we change that ?
In mugen its done differently and chained with time and not frame based , so this one is not that smooth, its kinda spitting afterimages pe frame
 
Last edited:
Trails should gradually decrease opacity when they fade out, this does not happen here, how can we change that ?
In mugen its done differently and chained with time and not frame based , so this one is not that smooth, its kinda spitting afterimages pe frame

Basically, instead of just not drawing the trail sprite anymore once it expires, you'd draw it with a little less opacity tied to the time. Drawmethod has 255 levels of opacity for each color channel, same as any image editor, so you can fade it out however you like. Wouldn't be much of an add on to the exiting code.

DC
 
so we can do alpha + percentage based opacity at teh same time ?
No opacity here drawmethod {scalex} {scaley} {flipx} {flipy} {shiftx} {alpha} {remap} {fillcolor} {rotate} {fliprotate}
 
It's in the scripted drawmethod properties. First you set alpha 6, which defaults to all 50%. But then you can override that with channels R, G, and B to have whatever transparency you want. I forget the old functions because I don't use them (I've replaced them with better ones for new release and never touched the old ones again). They're in the manual somewhere.

DC
 
so we can do alpha + percentage based opacity at teh same time ?
No opacity here drawmethod {scalex} {scaley} {flipx} {flipy} {shiftx} {alpha} {remap} {fillcolor} {rotate} {fliprotate}
@bWWd I'm using a similar method since the SOR2X but based on the current channel value instead of time. When the channel reaches 0, the shadow is removed.


C:
void main()
{//Set gradual channel reduction effect in each spawned entity
    void self        = getlocalvar("self");
    int alpha        = 6;
    int chStart        = 160;
    float channel    = getlocalvar("channel"+self);
    float reduce    = 3;

    if(getlocalvar("channel"+self) == NULL()){setlocalvar("channel"+self, chStart);}
 
    if(channel >= chStart){
        changedrawmethod(self, "enabled", 1);
        changedrawmethod(self, "alpha", alpha);
        changedrawmethod(self, "channelr", channel);
        changedrawmethod(self, "channelg", channel);
        changedrawmethod(self, "channelb", channel);
        setlocalvar("channel"+self, channel-reduce);
    }
    if(channel < chStart){
        changedrawmethod(self, "channelr", channel);
        changedrawmethod(self, "channelg", channel);
        changedrawmethod(self, "channelb", channel);
        setlocalvar("channel"+self, channel-reduce);
    }
 
    if(getlocalvar("channel"+self) <= 0){killentity(self);}
}

EDIT: I still need to update this code to work with entityvars but it can give an idea of the concept. In addition my method uses entities instead of drawing sprites directly because I have other routines tied to "self" pointer and will not work with NULL() pointers for the global drawmethod.
Let me know in case you need more details.
 
Last edited:
@DCurrent This topic reminded me of a minor issue (or maybe an intentional behaviour) I found in the drawmethod, for some reason I can't apply channel and tint functions together. In SORX shadow trails I want to apply a light blue tint effect similar to some fighting games but it will cancel the channel reduction.
I didn't look at the source code yet but maybe we could try to fix this in the v4.0.
 
Back
Top Bottom