Jump to content

Photo

More Metroid-Style Scripts- A Screw Attack and a Spring Ball


  • Please log in to reply
16 replies to this topic

#1 ywkls

ywkls

    Master

  • Members

Posted 14 December 2014 - 10:31 AM

Okay, I have a script I've found on another forum I'd like to refine to create some genuine Metroid-based effects. I'm working with the latest version of Zelda Classic 2.5. I'm listing all of the scripts I'd like to get in one topic since that seems to be easier than creating separate topics. (Who knows, maybe I'll get both of them?)  Anyway, here is the script I'd like to have tweaked.

 

http://www.purezc.ne...ic=64847&page=2

 

With the current setup, there are a few things which I'd like to have changed. The first is that the animation sprite for the weapon being generated should stay onscreen for more than one frame so that you can actually see it as it hits an enemy. (even better would be that it is working and visible constantly while you are jumping.) The second is that I'd like to be able to use it to destroy combos that have a certain flag whenever you hit it (say script 1). This flag would probably work better if it was a combo's internal flag, since otherwise you'd have to set up a variable that told the game the combo ID for the combo to become whenever this flag was triggered. The third thing is that how much damage it does the enemy seems to not be working right. I tried changing the value referenced in the script, but unless I set the enemies Script Weapon Defense to One-Hit Kill it doesn't seem to hurt them; only stun them. Finally, I'm not sure based on my testing so far; but is your character invulnerable while the weapon is in effect? If that is possible to add, I'd like that too.

 

Okay, now for the second script request which may be hard or impossible since I don't have a script to refer to. That would be the spring ball. With my current setup, I've substituted the Morph Ball with the Flippers; filling any passage narrow enough to require its use with unwalkable water. The problem lies when trying to give a character a spring ball. Obviously, you can't really jump whenever you're underwater and just making the combo where you have to ascend walkable won't work since I also want it to be impassable when you're walking regularly so it needs to be a water-type combo. Here's a screenshot for an example.

 

ZGCfW5M.png

 

The pale combos are water. The horizontal ones are unwalkable while the vertical ones aren't. So when you approach a ledge, you can't go back up unless you can jump somehow. Ideally, the resulting item needed to move vertically in water would have to jump as high as the Roc's Feather would when set to a Jump Height Modifier of 4. If this isn't possible or there is another way to do this that's easier, I'd like to know. Thanks in advance for any assistance!



#2 ywkls

ywkls

    Master

  • Members

Posted 31 December 2014 - 10:56 PM

Well... it has been a couple of weeks since I started this and no one has commented or anything so I'm going to post a suggestion on how to do one of the things that I'd like and see if someone can merge the script here http://www.purezc.ne...ic=64847&page=2 with the script here http://www.purezc.ne...ic=65455&page=2 for the Pegasus Boots.

 

The Pegasus Boots script allows you to create an animation that follows behind your character, change Flag 98 combos into a combo of your choice and produces a sound for using the item and hitting an object which either breaks or ignores it. The main difference I can see is that the Screw Attack would be in use while you were jumping, which my game will do by pressing L and would not an item that is always active rather than one you had to equip to A or B. And of course, damage enemies. While I'm using the latter script in another quest, I don't really know how to combine the various functions in the two but the fact that the Pegasus Boots could do something like what I wanted is what prompted me to make this request in the first place. I know it may take some time for people to get around to my request, but at least this way they have something to work with other than my ideas. 

 

By the way, I'm beginning to fear that the spring ball may be impossible so I took down the relevant screenshot.


Edited by ywkls, 31 December 2014 - 10:57 PM.


#3 ywkls

ywkls

    Master

  • Members

Posted 13 February 2015 - 10:41 PM

I still haven't given up on this and I do have a portion of the code worked out on my own. Some bugs still exist, so I'm posting the revised code in the hopes that somebody can point me in the right direction. The purpose of this code is to create an item that works like the screw attack. It creates a trail behind you as you jump, destroys certain blocks and damages enemies. Currently, it only does the first of these and that is somewhat buggy. (The trail is directly beneath you rather than following you.) Enemies seem to be stunned unless their defenses for script weapons are set to One-Hit Kill.

Spoiler

 

I suspect that part of the reason that it isn't working is because the original code for replacing combos with flag 98 with the under combo was designed to be used when you're not jumping. I'm definitely going to do some more research on a method to interact with flags while jumping in sideview gravity, but at least I'm closer to a solution than I have been for a while. If anybody wants to lend a hand, I'd really appreciate it.

 

Edit: I didn't notice this when I posted this update, but the completed Pegasus Boots Script justin uploaded includes a way to damage enemies with the item when you use it. The code is now updated with a solution to that problem. The only thing it lacks is whatever is keeping it from interacting with combos that have the appropriate flag. (And the buggy animation for the trail as you jump.) I might figure it out on my own by putting together other scripts the way I have been doing, but from past experience I know that will take me a long time so I'd still like any input that I can get.


Edited by ywkls, 13 February 2015 - 11:33 PM.


#4 justin

justin

    Adept

  • Members

Posted 13 February 2015 - 11:23 PM

if(ComboFI(Link->X+8,Link->Y+8,CF_DASH) && Screen->ComboS[loc] == 1111b)

 

that's the part of the code that is whether Link is interacting with a "flag 98".  it is checking that the combo is fully solid.  and that the center of Link (x+8, y+8) is on the "flag 98".  since it is a solid combo its unlikely that Link's center is on the combo.  I can't remember exactly, but for the Pegasus script that you've pulled that from, it was manually manipulating Link's x/y position, which you aren't doing here.  by manually manipulating it, you can make Link move over solid combos.

 

you might want to go with a directional approach like

if (Link->Dir == DIR_RIGHT && ((isSolid(Link->X+16, Link->Y) && ComboFI(Link->X+16,Link->Y,CF_DASH) ) || (isSolid(Link->X+16, Link->Y+15) && ComboFI(Link->X+16,Link->Y+15,CF_DASH) ) )

 

maybe create a function to simply that doing the checks based on direction.  or at least a function isDashSolid that checks the coords for both solid and dash flag.



#5 ywkls

ywkls

    Master

  • Members

Posted 14 February 2015 - 12:07 AM

Spoiler

 

That's my revised collision code, based on your recommendation. It is doing something, because the SFX_PEGASUSBREAK is playing. I think that the code that defines the variable loc needs to be changed too since that's what governs which combo is changed to the under combo (or whatever). I tried changing it as shown below, but it doesn't seem to make any difference. However, the under combo is appearing in both versions of the script; below the combo with flag 98.

int loc = ComboAt(Link->X+16, Link->Y+15);

I tried placing the flag 98 above the combo I wanted to change, but that just made it where nothing happened when I hit the combo. Thanks for the Pegasus Boots Script I used for most of this and the ideas on modifying this one. If you can figure out what's wrong, that would mean I have everything I need for this particular project.



#6 justin

justin

    Adept

  • Members

Posted 14 February 2015 - 10:23 AM

i meant to check the points in the direction link was going.  yours is checking that he is going in a direction (up, left, right), and then only certain points.  but there is no need to check the left of link points when he is travelling to the right...

 

link's sideview hitbox is Link->X to Link->X+15, and Link->Y to Link->Y+15.  So if he's going left, you want to check Link->X-1.  If he's going right, Link->X+16.  If he's going up Link->Y-1.  And down, Link->Y+16.  Then you typically want to check at least 2 points in the opposite plane, so if moving left or right, you'd want to check the top and bottom, so you'd check Link->X-1 or Link->X+16, and Link->Y AND Link->Y+15.

 

now in sideview when jumping, which i'm understanding is what you're doing here.  Link is probably moving diagonally.  So you'd also want to check up/right, up/left, down/right, down/left.  That's 8 different checks.  Now determining that Link is moving those diagonal directions is gonna be tricky.  You could keep track of his previous x/y position and compare.  You could watch the Link->Jump value.  But really i can't think of a good way because of how sideview gravity works...

 

what i would do is create a function to check all that, and return the location of the dash block you are colliding with.  so you're code would look like...

int dashblock = GetDashSolid();
 
if(dashblock>0)
{
// do break block stuff
}
 
// and here's the sample of the isDashSolid() function...
int GetDashSolid()
{
   if(Link->Dir == DIR_LEFT && Link->InputLeft)
   {
      if (isDashSolid(Link->X-1,Link->Y) ) return ComboAt(Link->X-1,Link->Y);
      if (isDashSolid(Link->X-1,Link->Y+15) ) return ComboAt(Link->X-1,Link->Y+15);
   }
   else if(Link->Dir == DIR_RIGHT && Link->InputRight) 
   {
      // etc
   }
   // etc with other directions   
 
   return -1;
}
 
// and the isDashSolid function
bool isDashSolid(int x, int y)
{
   int loc = ComboAt(x,y);
   return (ComboFI(loc,CF_DASH) && Screen->ComboS[loc] == 1111b)
}

Edited by justin, 14 February 2015 - 12:35 PM.


#7 justin

justin

    Adept

  • Members

Posted 14 February 2015 - 01:46 PM

oh, and i'm not sure why the "dust" is being drawn under you instead of behind, that dust drawing code looks like it should work.  the only thing i can think is that when jumping in sideview, Link->Dir is being set as DIR_UP, or the ScrollDir variable is being set somewhere along the way to DIR_UP, and not reset.  the dust code wasn't designed to be used when jumping, so i never tested it in that regard.

 

 

you're doing pretty good, for just mashing some scripts together.  but since these scripts (especially pegasus boots) where designed to for one specific purpose, and are fairly complex in that regard, you're gonna have a hard time making it work.



#8 ywkls

ywkls

    Master

  • Members

Posted 14 February 2015 - 06:06 PM

It has taken five months of studying various scripts, getting advice and reverse engineering other scripts but this script is now 90% done. Here's what I've got.

 

Spoiler

 

It took a lot of experimentation with the code I posted earlier to get to this point. This combines the Pegasus Boot Script created with the aid of justin and Lejes with the Shoryuken script by MoscowModder. The resulting code damages enemies, destroys a block above you if it has flag 98 and leaves a trail behind you as you jump. That trail points directly down, so it obviously needs improvement and a thorough study would have to be made in order to fix it.

 

At the moment my brain is still tired from wrestling this together. Considering some of the things I've asked for help on since I started posting, i'd say that I've made a lot of progress. I don't think I'm quite up to the point where I can script my own enemies and even something like this took a great deal of mental gymnastics; testing various solutions and then abruptly getting insight to develop. I want to thank anybody who has ever written a script, because you've helped me to reawaken my dormant skills in this department. I want to especially thank justin, since he's helped out several times when I have posted requests and without his work on other stuff I don't think this would have been possible.

 

I'm not saying my solution is the best. (It clearly isn't, based on the dust animation alone.) I'm just proud of how far I've come and happy to get this script to a (mostly) functional level. Without the help I've gotten, I couldn't have done it. I plan to continue learning so that maybe one day (in the far, far future) I won't have to request scripts any more. Until then, thanks to everyone!



#9 Lejes

Lejes

    Seeker of Runes

  • Members
  • Location:Flying High Above Monsteropolis

Posted 14 February 2015 - 06:31 PM

Screen->FastTile(0, dX, dY, T_DUST+ Floor(Dust_Array[i]/DustASpeed), DustCSet, 128);

 

This is the code that's drawing the dust, yeah? Take a look at dY. It's being assigned as drawY + 8 if Link is facing left or right, and drawY is being set to Link->Y every frame. I assume this is why the dust clouds are always appearing below him. Those global drawX and drawY variables were meant for Saffith's ScrollFix function, so I'd be leery of repurposing them to draw other things.



#10 justin

justin

    Adept

  • Members

Posted 14 February 2015 - 08:57 PM

Screen->FastTile(0, dX, dY, T_DUST+ Floor(Dust_Array[i]/DustASpeed), DustCSet, 128);
This is the code that's drawing the dust, yeah? Take a look at dY. It's being assigned as drawY + 8 if Link is facing left or right, and drawY is being set to Link->Y every frame. I assume this is why the dust clouds are always appearing below him. Those global drawX and drawY variables were meant for Saffith's ScrollFix function, so I'd be leery of repurposing them to draw other things.

drawY+8 means it draws halfway down Link's sprite to look like it's being created by his feet as he dashes. I don't know the desired effect for this spin attack script. But I'm not interpreting the problem being that the "dust" is halfway down the sprite and behind, but rather beneath, suggesting a dY value like Link->Y+16 or more, like if Link->Dir = DIR_UP from the code.

It's using the scroll fix variables because one of the requests for the Pegasus boots edit that I did was that the dust draw while scrolling, and that solution with using drawX and drawY with an array of the dust positions was the best way I could think to do it. Not sure how they are being repurposed wrong when I'm using them for their purpose...

@ywkls, can you post a test quest or video of the script in use, so I can see what is happening with the "dust" drawing?

#11 ywkls

ywkls

    Master

  • Members

Posted 14 February 2015 - 09:35 PM

Alright, here's a sample quest with you appearing on screen with the item nearby and a block with flag 98 already placed in midair.  I basically took my completed quest, created a screen on it just to test this item and then blocked it off so you couldn't leave and set the game to start you on that screen.

 

https://www.dropbox....lassic.qst?dl=0

 

I should note that the animation draws whether you are in the air or on the ground as shown by the following screenshots.

 

5VfG7EF.png

 

In midair...

 

hOcBiLz.png

 

On the ground...

 

I suspect this is happening on the ground because I set it to activate the Dust drawing code whenever you press L, even if it is held down. I hope that the dropbox file is easier to access than the 2shared one you said you had trouble with before. Now that I've opened an account there, I'll probably use it for any future uploads. Thanks for your assistance.



#12 justin

justin

    Adept

  • Members

Posted 14 February 2015 - 10:08 PM

Oh, I see what is happening! You aren't actually calling the ScrollFix function anywhere, so those variables aren't being set, and your "dust" won't draw while scrolling. The scrollDir variable is being initialized as 0 which is DIR_UP, making the "dust" draw under him always. Either add the ScrollFix function to the top of your global loop, initialize the scrollDir variable as -1, or remove all instances of the ScrollFix and scrollDir stuff in the script if you don't care about drawing during scrolling.

#13 ywkls

ywkls

    Master

  • Members

Posted 14 February 2015 - 11:53 PM

Okay, here's my idea on a solution. This is still a bit crude when it comes to the animation but it is so close to what I want that the difference almost doesn't matter. The script also needs alterations to work with the High Jump Boots. I've got a partial solution which let's you destroy blocks with the regular boots even with other blocks nearby but the High Jump Boots part doesn't work unless the block is sitting in midair by itself. So here's my code.

Spoiler

 

The animation of each part of the trail is treated as a function of i where i is which segment of the animation in the DustArray it is. Then each segment of the trail is offset. Each segment seems to be moving up and down as it spawns, but otherwise arcs behind you as you jump. (And if you're standing still or on the ground, but that's a completely different problem.)

 

The settings for the variable loc which determines which combo is changed to the under combo were obtained through trial and error. At the current settings, the combo vanishes if you have the I_NORMALJUMP or I_HIGHJUMP. The only difference is with the first, it does that even if there are other unwalkable combos nearby without flag 98 while with the second it doesn't.

 

I've tried a few different settings for the value of the variable loc for the I_HIGHJUMP and so far this is the only one I've gotten to work anywhere close to the way it should. I'm kind of shooting in the dark with these codes and whenever I get close to a solution and then get stuck, I post what I've developed. Sometimes that helps me get ideas on my own and sometimes somebody posts something that gives me ideas. Or they offer a solution. Either way, this code is getting very close to working the way I envisioned it when I created this thread and for that I am grateful.



#14 ywkls

ywkls

    Master

  • Members

Posted 15 February 2015 - 09:57 AM

Coding things for sideview gravity is weird... I got both the Normal Jump and Hi-Jump to work properly now. I don't know how I did it. Really, I don't. I just kept trying various ideas until one of them worked. This one does.

 

Spoiler

 

As near as I can figure, combo positions are being figured out in the following way: X is the left of the screen and Y is the top. The way it is now, any breakable blocks must have nothing that impedes horizontal movement directly below and one space either left or right of them. For example, in the following screenshot the block at the top could be broken but any placed next to a wall couldn't.

 

hOcBiLz.png

 

That isn't a particularly difficult problem to work around, so I'm going to ignore it. But if anyone comes up with a solution, that would be cool too. As for the animation of the dust, to really get an arc the segments' positions would have to be altered via a quadratic equation. While I'm pretty good at algebra, figuring out the right equation is bound to take a little time. For now, the way I have it set up is how I'm going to leave it until I either discover the equation or somebody else suggests one.

 

This script is a derivative work, using MoscowModder's Shoryuken Script and justin's Pegasus Boots Script. It may be used by anybody who wants to and I encourage modification to improve it since I don't have any idea how long it would take me to get this finished. However, I can definitely tell that my scripting skills are getting better. Part of what holds me back is having to test my solutions without any idea whether they will work and still not knowing the language intuitively. I know this has been the result of help from others and I'm definitely going to need it for a while yet. Thanks to everyone who has assisted me!



#15 justin

justin

    Adept

  • Members

Posted 15 February 2015 - 10:39 AM

Here goes round2 trying to make this post, hopefully this doesn't get all eaten up as well...
 
I see you opted to remove the ScrollFix function.  In that case there are a lot of unnecessary things you can dump from the script.  One is the whole "dust" drawing method that you are using, I wrote that so that the dust could draw while scrolling.  You can just revert to this dust code which is a lot simplier and easier to edit.  It uses lweapons to draw the "dust".  First it finds one's that are currently on screen and moves them depending on your direction.  Then it creates a new one.  It does this every 4 frames.  It would be easier to modify this code to move the "dust" in an arc like you want.  Instead of the Dust->Y-=3 or whatnot you'd put your equation for that direction.
 
void DustDrawLW(){
   lweapon Dust;
   if(DashCounter%4 == 0){
      for(int j=Screen->NumLWeapons();j>0;j--){
         Dust = Screen->LoadLWeapon(j);
         if(Dust->ID != LW_SCRIPT10) continue;
         if     (Link->Dir == DIR_UP)    Dust->Y-=3;
         else if(Link->Dir == DIR_DOWN)  Dust->Y+=3;
         else if(Link->Dir == DIR_LEFT)  Dust->X-=3;
         else if(Link->Dir == DIR_RIGHT) Dust->X+=3;
      }//end for loop
 
      Dust = Screen->CreateLWeapon(LW_SCRIPT10);
      Dust->OriginalTile = T_DUST;
      Dust->CSet = DustCSet;
      Dust->Y = Link->Y+8;
      Dust->X = Link->X;
      Dust->NumFrames = DustAFrames;
      Dust->ASpeed = DustASpeed;
      Dust->DeadState = DustAFrames*DustASpeed;
   }//end dust if
}
 
If you are going to keep the dust drawing method that you are currently using then you can fix it up a bit too.  You added some dXOffset/dyOffset variables and code, which are sorta unnecessary.  You just finished checking all the directions, you could have just changed dX/dY with your new (i* 8)-24 formula at that time.  This current code won't draw the "dust" if you are moving up or down.
 
dXOffset = (i*8)-24;
dYOffset = (i*8)-16;
if(Link->Dir== DIR_LEFT)Screen->FastTile(0, dX-dXOffset, dY-dYOffset, T_DUST+ Floor(Dust_Array[i]/DustASpeed), DustCSet, 128);
if(Link->Dir== DIR_RIGHT)Screen->FastTile(0, dX+dXOffset, dY-dYOffset, T_DUST+ Floor(Dust_Array[i]/DustASpeed), DustCSet, 128);
 
 
 
Next is this...
if((Link->Dir == DIR_UP || Link->Dir == DIR_LEFT || Link->Dir == DIR_RIGHT)&& DashCheck(Link->X+8,Link->Y+6,true) != 2){
   drawY = Link->Y;
   drawX = Link->X;
}
else{
   ScrewAttackCollision = true;
   DashCounter = 0;
}
 
the first part of that if statement is unnecessary.  Its only setting the drawY/drawX variables from the ScrollFix function which you aren't using, and they were being set for a specific reason with the Pegasus Boots script anyways.  You don't need the drawX/drawY variables, and even if you were using the ScrollFix function you don't need to set drawX/drawY here.  You can just use your text editor to find and replace all instances of them with Link->Y for drawY and Link->X for drawX.  Then you'd change that else statement to be an if which is the opposite of your existing if statement, something like...
 
if(Link->Dir == DIR_DOWN || DashCheck(Link->X+8,Link->Y+6,true) == 2)
 
You can ditch this, and the associated variables anywhere else in your code.  Again it was used for scrolling.
// save our sword sprite for when scrolling
dashSwordTile = mysword->Tile;
dashSwordCSet = mysword->OriginalCSet;
 
 
Now with your dashBlock breaking code you are arbitarily deciding where the dashBlock is that is being hit.  You aren't accounting for direction of movement.
if((Link->Dir == DIR_RIGHT || Link->Dir == DIR_LEFT || Link->Dir == DIR_UP)   && ((Screen->isSolid(Link->X+16, Link->Y) && ComboFI(Link->X+16,Link->Y,CF_DASH) ) || (Screen->isSolid(Link->X+16, Link->Y+15) && ComboFI(Link->X+16,Link->Y+15,CF_DASH) ) )){
loc = ComboAt(Link->X+8, Link->Y-8);
 
So if Link is moving any direction but down (i'm assuming you don't want to be able to break blocks from above?), and the combo at Link->X+16, Link->Y or Link->X+16, Link->Y+15 is solid and a dashBlock then break it.  Now Link->X+16 is right of Link.  You aren't checking any other directions, and Link may not even be moving right.  If that is true, then you arbitrarily decide to change the combo at Link->X+8, Link->Y-8, so the combo at Link's center horizontally, but halfway above him.  Not the combo to the right?  With the highjump you are checking Link->X+16, Link->Y and Link->X+16, Link->Y-15, right of Link's top and up/right of Link.  Then changing the combo at Link->X+16, Link->Y-16, different position, and not necessarily the same position if it was Link->X+16,Link->Y that evaluated true, and not Link->X+16,Link->Y-16.
 
I'd recommend rereading the post I made earlier in this thread with regard to how to decide which way link is moving, and what dashBlock he is going to be colliding with.  This one, http://www.purezc.ne...469#entry944373

Edited by justin, 15 February 2015 - 03:55 PM.



0 user(s) are reading this topic

0 members, 0 guests, 0 anonymous users