Bigger shadow?

mersox

Active member
Hello all. I need to add a bigger shadow sprite in my game. After a lot of tweaking, this is the best I could make shadow06 work:

bor%20-%200005.png


Is it possible to add a custom shadow07 to the engine/mod? I can not simply change thesize of the sprite; if I do, its offset gets all funked up.

P.S.: I know it's common to use gfxshadow when working with digitized sprites like these. It's just that in my opinion, old school circle-shaped shadows are better for gameplay in 3D beat em ups.
 
You can disable the engine shadow and spawn a custom entity for shadow, which binds itself at the parent.

Code:
void main()
{
    void self = getlocalvar("self");
    void parent = getentityproperty(self, "parent");
    
    
    float x = getentityproperty(parent, "x");
    float z = getentityproperty(parent, "z");
    float a = getentityproperty(parent, "a");
    changeentityproperty(self, "position", x, z-2, 0);    
    
}
 
Thank you, Ilu. So if I understand correctly, this entity will remain on the floor at all times, and not jump along with the character, is that correct?

Should I add that script at spawn animation of the shadow entity?

Now... let's say all goes smoothly... would it be possible for this shadow to change shape/size during gameplay? The way I have set up the game now, there is a smaller shadow for jump animations (using fshadow). Can jump animation of the parent entity affect the animation of the shadow entity? I guess I can add script in jump animation of parent, but how do you call a binded entity in script? Sorry for all the questions.
 
That code should be place as a SCRIPT at the entity header (or called as script, for example script data/scritps/yourscript.c).
Yes, it should follow its parent.

About your question, yes its doable. You need to make it check which animation its parent is, and make it change to a specific animation to follow it. On that animation, you need to make it check the parent animation again.
 
mersox said:
Should I add that script at spawn animation of the shadow entity?

You can declare that as updatescript as Ilu posted OR in shadow's animation like this:
anim idle
@script
    void self = getlocalvar("self");
    void Parent = getentityproperty(self, "parent");

    if(Parent!=NULL()){
      float Tx = getentityproperty(Parent,"x");
      float Tz = getentityproperty(Parent,"z");
      float Health = getentityproperty(Parent,"health");

      if(Health>0){
        changeentityproperty(self, "position", Tx, Tz);
      } else {
        killentity(self);
      }
    }
@end_script
loop 1
delay 1
offset 45 11
frame data/chars/misc/board.gif
frame data/chars/misc/board.gif

This is from board which follows rider's movement BTW
The health check is to remove the board/shadow if parent entity dies

As for which one is better, since you want the shadow to change size, update script would be the better option
 
Nice touch with the health check.
Just a tip: its not an updatescript and can not work if you use this way (some scripts doesn't work well or have delays if you use as a update script). Its an Script, which is triggered everytime and not just when the engine updates. For example, Script will happen before updatescrit, updatedscript or ondrawscript.

You should paste this on the entity header, just where you set palettes and such:

Code:
script @script
void self = getlocalvar("self");
void Parent = getentityproperty(self, "parent");

    if(Parent!=NULL()){
      float Tx = getentityproperty(Parent,"x");
      float Tz = getentityproperty(Parent,"z");
      float Health = getentityproperty(Parent,"health");

      if(Health>0){
        changeentityproperty(self, "position", Tx, Tz);
      } else {
        killentity(self);
      }
    }
@end_script

Pay attention there is a "SCRIPT" before the "@script", ok?

For the animation check, there are several ways to do this. Maybe it would be better to check for the internal flags, but that would require more work.

You can simply go with this:

Code:
script @script
void self = getlocalvar("self");
void Parent = getentityproperty(self, "parent");
void animationid = getentityproperty(Parent,"animationid"); // gets the parent animation

    if(Parent!=NULL()){
      float Tx = getentityproperty(Parent,"x");
      float Tz = getentityproperty(Parent,"z");
      float Health = getentityproperty(Parent,"health");

      if(Health>0){
        changeentityproperty(self, "position", Tx, Tz);
      } else {
        killentity(self);
      }
    }
	
	// animation check routine
	
	if (animationid==openborconstant("ANI_JUMP")){
		changeentityproperty(self, "animation", openborconstant("ANI_JUMP"));
		
	}
@end_script

And so on. You can even use a frame check to make it bigger again when the character lands.

Thinking more about this, I think you can make it replicate all the animations from the parent (IOW, you would need to add every animation the parent have). But dunno if this will worth the trouble. There is a sync function in openbor but I never understand it (and its not too much documented).
 
O Ilusionista said:
...There is a sync function in openbor but I never understand it (and its not too much documented).

Sync probably isn't useful for this, though there are plenty of ways and it seems like you guys have it in hand.

Sync synchronizes the frame timing between two animations of the same entity on transition.

Let's say you have an autoscroll stage. Both IDLE and WALK are identical - a four frame running animation. Looks great until the player moves, and there's a jarring transition because you're going directly to WALK frame 0 from whatever frame of IDLE you were in. On screen, it looks like the character just lock stepped for a second.

Sync fixes this by forcing the two animations to transition in time with each other. So if you were in IDLE frame 3 when you started walking, then you'd transition directly to WALK frame 3.

DC
 
I really appreciate the replies. I feel very ashamed in admitting I haven't been able to make it work.  I have tried this in many ways (either calling a script from the script folder, or having the script in the header, or having it in spawn animation checking for frame 0) and in almost all of them the result is the same: the shadow doesn't follow its parent.

When having the script in the header of the shadow entity, I have to leave out the "script" word that is right before the "@script", or else the game crashe-- er I mean, exits gracefully while recording an entry on the log ;)

So this is how my files look now:

Shadow entity:
name shadow7

health 0
type none
shadow 0
palette none
script @script
void self = getlocalvar("self");
void Parent = getentityproperty(self, "parent");

    if(Parent!=NULL()){
      float Tx = getentityproperty(Parent,"x");
      float Tz = getentityproperty(Parent,"z");
      float Health = getentityproperty(Parent,"health");

      if(Health>0){
        changeentityproperty(self, "position", Tx, Tz);
      } else {
        killentity(self);
      }
    }
@end_script

anim idle

loop  1
delay  1
offset 42 15
frame data/chars/misc/shadow/shadow7.gif
frame data/chars/misc/shadow/shadow7.gif


anim walk

loop  1
delay  1
offset 42 15
frame data/chars/misc/shadow/shadow7.gif
frame data/chars/misc/shadow/shadow7.gif

Right now it's type none, I tried with type npc as well and nothing.

Parent entity:
name red_zeo_ranger
health 20
mp 40
speed 25
shadow 0
type player
diesound data/sounds/tommylong12.wav
nosame 1
com F F freespecial3
com D F A freespecial1
com A2 freespecial2
riseinv 1 0
makeinv 2 0
weaploss 3
modelflag 1
throwdamage 2
load shadow7
throwframewait 1
falldie 2
dust dustbig dust dust
animationscript data/scripts/script.c
noquake 1
jumpheight 5
jumpmove 7 7
atchain 1 1 2 3
icon data/chars/red_zeo_ranger/icon.png
palette none
load spark
bounce 0


anim spawn
loop 0
offset 101 228
delay 10
@cmd spawn01 "shadow7" 0 0 -1
frame data/chars/red_zeo_ranger/idle06b.png

....

I tried with spawnbind but then the shadow jumps along with the character.

Sorry everybody
 
Sorry, it was my mistake.

The code to bind it is this:
void main()
{
    void self = getlocalvar("self");
    void parent = getentityproperty(self, "parent");
     
    float x = getentityproperty(parent, "x");
    float z = getentityproperty(parent, "z");
    float a = getentityproperty(parent, "a");
    changeentityproperty(self, "position", x, z-2, 0);   
}

This won't bind the entity to the parent, it will simply copy the X and Z position of the parent and set the a position to 0.

So the whole code would be

@script
void self = getlocalvar("self");
void parent = getentityproperty(self, "parent");

    if(Parent!=NULL()){
    float x = getentityproperty(parent, "x");
    float z = getentityproperty(parent, "z");
    float a = getentityproperty(parent, "a");
    changeentityproperty(self, "position", x, z-2, 0);   
      float Health = getentityproperty(Parent,"health");

      if(Health>0){
    changeentityproperty(self, "position", x, z-2, 0);   
      } else {
        killentity(self);
      }
    }
@end_script

Or you can change the bind code to:
changeentityproperty(self,"position",x,z-2,NULL())
 
the result is the same: the shadow doesn't follow its parent.

Oh I forgot to tell you how to spawn the shadow. You should be using this function:

Code:
void spawner(void Name, float dx, float dy, float dz)
{ // Spawn certain entity and set it as child
   void self = getlocalvar("self");
   void Spawn;

   Spawn = spawn01(Name, dx, dy, dz);
   changeentityproperty(Spawn, "parent", self);
}

like this:

@cmd spawner "Shadow7" 0 0 0

This spawner function is spawn01 + setting spawner as parent
BTW you should set setlayer 1 in Shadow7.txt to ensure it won't overlap other entities
 
It worked like a charm. Thanks!

After some testing I don't think I will need the shadow to change sizes during gameplay. Originally I though that the new custom shadow would be too big for certain animations but it doesn't seem to be the case after testing. You guys can be the judge of that when I post new gameplay videos.

The only drawback right now is that the shadow doesn't recognize platforms, but honestly I don't think that will be an issue for this particular game.

Thanks again! I love this community.
 
Hey Mersox, finally I was able to actualy test the script.

Here is the script I use:

Code:
script @script

void main()
{

void self = getlocalvar("self");
void parent = getentityproperty(self, "parent");

    if(parent!=NULL()){
    float x = getentityproperty(parent, "x");
    float z = getentityproperty(parent, "z");
    float a = getentityproperty(parent, "a");
    changeentityproperty(self, "position", x, z-2, 0);
    }
}
@end_script
NOTE: if you use this code as ONDRAWSCRIPT, there will be a 1 tick delay.


I am not using the health check because I don't need it.
You need spawn the shadow as " @cmd  spawner "Shadow7" 0 0 0"
 
Back
Top Bottom