Jump to content

Photo

My Script Wishlist and Your Script Ideas


  • Please log in to reply
242 replies to this topic

#106 ywkls

ywkls

    Master

  • Members

Posted 27 June 2015 - 07:15 PM

@Lejes- Your suggestion for offsetting the rotation of the barriers worked out. I'd been experimenting with that equation for a while, trying to figure out how all the parts fit together. I had learned how to shift the center of the circle, the radius of the circle and the direction of movement but this is a new one for me.

 

However, the 'enemy can walk through the wall' bug has resurfaced even though every combo onscreen is a 'No Enemy' combo, except the places where you can walk. Is this a common bug when it comes to ghosted enemies?

 

Two more things... I know some functions and equations use radians instead of degrees, but what exactly is the difference between them? I know one measures from zero to 360 and the other from -180 to 180 (I think), but how does the different forms of measurement affect the movement of something?

 

Second topic, if the script works without the Ghost_Waitframe, why include it? And as for the Ghost_Deathanimation, I've never been able to get it to work properly even by copying a line directly from another script and substituting the correct information into the function.

 

I've come a long ways in my usage of ghost.zh and your tutorial has certainly helped but I still have much to learn.

 

@Everyone  Else- Next up, scripting some more enemy ideas I had. To that end, how do you change only one of an enemies defenses? For example, if you wanted a foe to temporarily be invulnerable, and then later weak to just one type of weapon; what command would you use?

 

Could an enemy grab Link and throw him across the room? Could an enemy have the flag "Only visible with Lens of Truth" or "Is Invisible" turned on and off?

 

I'm also open to any suggestions on scripting ideas. (I can't think of everything on my own.) One I conceived of a while back was a larger than normal dodongo. I had a member offer to script it then, but he never got around to it. (I don't mind, which is why if you don't know; I'm not reminding you who it was.) 

 

So, I can see ways to change the animation and stop the movement whenever a super bomb is laid in front of it, but what about detecting the super bomb itself? It would have to be on the proper side, at whatever level the mouth of the enemy is and (presumably) not yet exploded to do damage.

 

I've been reviewing bosses in LTTP and so far the only ones that I don't think have been scripted are Mothula, Arrghus, Vitreous and Trinexx. Mothula doesn't really need as script, since he's just a big, flying enemy in a room with lots of traps and spikes. (The room itself would probably be scripted, though.)

 

For Arrghus, you'd need to make all of the eyeballs that hang onto him and have them designed where they'd be pulled to you when hit with the hookshot. The hard part of Arrghus would be getting him to jump offscreen and bounce around the room.

 

As I recall, the main body of Vitreous would sit there while the small eyes bounced towards you and it would occasionally shoot lightning bolts at you. It would be fairly easy to make the body invulnerable and immobile until the eyes died; then have it pursue you.

 

For Trinexx. you'd need both the Fire and Ice Rod and I don't really feel like adding the latter to my quest at this point.

 

Any suggestions on any of these, or other bosses from other games would be helpful!


Edited by ywkls, 27 June 2015 - 07:20 PM.


#107 Lejes

Lejes

    Seeker of Runes

  • Members
  • Location:Flying High Above Monsteropolis

Posted 27 June 2015 - 08:10 PM

You really need to use Ghost_Waitframe. I can't overemphasize this enough. Ghosted enemies don't walk through walls unless you set them to do so. A full circle in radians is 0 to 2π. If something is pointing at π radians, that means it goes straight left. If it's pointing at π degrees, it will go almost directly right because ~3.14 degrees isn't much.

 

You can change enemy defenses with npc->Defense[]. Ghost.zh has a couple more functions to streamline it, but if you just want to set one defense at a time that array is the easiest way. For an enemy that can throw Link across the room, I made such a thing for EotM #10. The code for it is all in the quest's script buffer. You can't toggle those miscellaneous flags. They're all read-only. You'd have to change the enemy's graphic whenever the lens was in use instead.



#108 ywkls

ywkls

    Master

  • Members

Posted 27 June 2015 - 10:11 PM

@Lejes- Adding Ghost_Waitframe seriously messed up my enemies' graphics when they changed form. In both cases, they didn't switch to the proper graphic either in terms of size or in animation. In one instance, the changed enemy didn't even appear in the right place. I have to conclude that this is another vagary of ghost.zh. (Or my lack of understanding thereof.)

 

On setting the enemies defenses, I'm guessing that the code would look something like this.

//To make invulnerable to arrows.
n->Defenses[NPCD_ARROW] = NPCDT_IGNORE;
//To make vulnerable.
n->Defenses[NPCD_ARROW] = NPCDT_NONE;

It's too bad about those flags... oh well. As for the entire radians and angle thing... that's one of the reasons why I attempted to explain common scripting terms and functions. I don't know for sure just by looking at most code which is being used on should be used.

 

I downloaded that enemy you created. I remember liking it, although I never tried it out. I'll have to look over the code when I get the chance. As always, thanks for your help.



#109 Lejes

Lejes

    Seeker of Runes

  • Members
  • Location:Flying High Above Monsteropolis

Posted 27 June 2015 - 10:22 PM

That's the problem with a lot of the ghost functions. You don't know in advance whether they'll use radians or degrees. You'll just have to keep ghost.txt on hand to check until you have them memorized. That defense changing code should work once you change "Defenses" to "Defense". Knowing the answer to the animation problem would require more info on your quest. It could be any number of things. Maybe the code isn't setting their size properly, or you don't have the tiles set up right, or combo 1 isn't properly invisible. Or are you using ZC's built in animation and having that conflict?


  • ywkls likes this

#110 ywkls

ywkls

    Master

  • Members

Posted 27 June 2015 - 10:38 PM

I'll post a test quest with the modified code. The only thing I really changed on the set up of the two versions of either script was changing Waitframe() to Ghost_Waitframe(this, n, false, false). With Waitframe(), the enemy always looks and moves right, but occassionally walks through walls. With Ghost_Waitframe, it doesn't look right and still walks through walls.
 

(Links now invalid since problem has been solved.)
Blind the Thief
 
Barinade
 
For comparison, my version of Blind the Thief which doesn't use ghost.zh directly. (Except for controlling the fireballs that the heads spew.)Old Blind the Thief
 
If you could please look them over and tell me what you think, I'd appreciate it. Current scripts are in the buffer.


Edited by ywkls, 30 June 2015 - 11:38 AM.


#111 Lejes

Lejes

    Seeker of Runes

  • Members
  • Location:Flying High Above Monsteropolis

Posted 28 June 2015 - 03:21 AM

I'm surprised it moved at all with Ghost_Waitframe. Something I hadn't realized is that enemies don't use built-in movement at all unless you use Ghost_Waitframe2. Otherwise ghost.zh takes over movement entirely. Shows how often I use built in enemy movement (i.e. never). The built-in movement also doesn't like enemies larger than 1 by 1, as it seems to only care about its top left tile in regards to walls (is that the walking through walls you were talking about?). Ghost_HaltingWalk4 will treat the enemy's full size properly, but in testing things while investigating this, I think I've stumbled across a serious oversight: HaltingWalk4 doesn't account for an enemy's Rate in any way. It just ignores that argument entirely.

 

The graphics issues may be kind of complex to solve, also. It seems like ghost.zh doesn't set Extend properly if you use tiles instead of choosing a combo, so you'll have to set it to 3 yourself in the script. Setting Ghost_TileWidth and Height (as opposed to just using the npc pointer equivalents) seems to handle the hitbox resizing automatically, at least.



#112 ywkls

ywkls

    Master

  • Members

Posted 28 June 2015 - 09:03 AM

I only have two scripts right now that actually use the Ghost_HaltingWalk4 function. In both cases they use a variable as the first argument. IS that necessary or can I just stick a number in there?

 

I don't have any examples that I can find in my scripts of the Ghost_TileWidth and TileHeight commands.

 

One of the reasons I was using built-in movement was because it was easier to do that try to figure out those movement functions.

 

It is possible that a lot of my other ghosted enemies have that problem where they might walk through the wall, but I haven't seen it so far.

 

I'll continue to do my on research on this. Please let me know if you find out anything else.



#113 Lejes

Lejes

    Seeker of Runes

  • Members
  • Location:Flying High Above Monsteropolis

Posted 28 June 2015 - 03:53 PM

npc ghost = Ghost_InitAutoGhost(this, enemyID);
ghost->Extend = 3;
Ghost_TileWidth = 2;
Ghost_TileHeight = 2;

I also tested ghost->OriginalTile and it does shift the graphics properly once Extend has been set. I think I prefer using combos, though. Then you can change Ghost_Data, use Ghost_Transform, and animation in general is a lot easier.



#114 ywkls

ywkls

    Master

  • Members

Posted 28 June 2015 - 04:41 PM

Alright, that's a first... while experimenting with the setup of Ghost_TileWidth and Ghost_TileHeight, I found it was necessary to use Ghost_Transform to activate them. After messing around for a while trying to figure out how to make Ghost_HaltingWalk4 move my enemy (which is now type Other), I decided to switch the way my enemy was displayed to combos.

 

Placing the combo number in Attribute 11, I used this code at the beginning.

int Blind = n->Attributes[11];
Ghost_TileWidth = 4;
Ghost_TileHeight = 2;
Ghost_Transform(this,n,Blind,-1,4,2);
int Collapse = Blind+1;

Then I left in this code in the area where it is supposed to be moving.

Ghost_HaltingWalk4(15, n->Step, n->Rate, n->Homing, 2, n->Haltrate, 45);

And finally I added Ghost_Waitframe(this, n, false, false) at the end of my while loop.

 

When I loaded my game, the enemy was invisible. Not only that, but I could still attack it. And, when I damaged it enough to trigger the change in form and execute the change in form and this code was run...

Ghost_Transform(this,n,Collapse,-1,4,2);

...something weird happened. Instead, I was warped as though to a Cave/Item cellar. A blank screen with bats on it and the item I was supposed to get sitting in the corner. And I didn't have any warp combos either as secrets or used as my ghost.zh invisible combos. I seem to recall that with the Armos Knight, I had to leave some blank space next to it's combo number corresponding to it's size. And a few of the combos next to my invisible combo are autowarp type. Could this be what is causing this unusual behavior?
 

I've gotten the enemy to appear the right size using these commands and the built-in enemy graphics selector, but haven't figured out how to make it move yet. Even using the built-in movement and Ghost_Waitframe2 causes it to look wrong when it changes form. (And it still walks through walls.)



#115 Lejes

Lejes

    Seeker of Runes

  • Members
  • Location:Flying High Above Monsteropolis

Posted 28 June 2015 - 04:58 PM

I went over how to use Ghost_HaltingWalk4 in the tutorial. You basically need a counter that starts at -1, then set that counter equal to the return value of HaltingWalk4 every frame. If there are no remaining Waitframes and the graphics are set up right, it shouldn't still be invisible. I know GH_INVISIBLE_COMBO can cause problems with warping if you have it set some warp combo type, but I didn't think ghost.zh used any other combos except for drawing (drawn combos don't have any of the actual properties of placed or FFC combos except animation).



#116 ywkls

ywkls

    Master

  • Members

Posted 28 June 2015 - 06:10 PM

Experimentation seems to confirm my theory about the adjacent combos affecting ghosted enemies. When the combos next to my invisible combo were Autowarp, I warped when it changed form. But when they were none, I didn't. 

 

My theory about having to have empty combos next to whatever combo the larger enemy is using seems to be wrong though. At one point, I somehow generated multiple copies of my foe, though only one was real. (Still don't know how I did that...)

 

Right now, it's appearance is fine. I've got it to start moving. The heads don't rotate unless it is in the collapse form. 

 

Here's the code.

Blind the Thief 6.0

The main difference I can see is that in the immobile section, the movement of the heads is only broken by the end of the timer. Whereas in the other part, it is just never run. So any thoughts on fixing this?


Edited by ywkls, 06 September 2015 - 10:09 PM.


#117 Lejes

Lejes

    Seeker of Runes

  • Members
  • Location:Flying High Above Monsteropolis

Posted 28 June 2015 - 07:05 PM

The heads don't rotate because you're constantly breaking out of the loop that increments angle, it seems. Your loop structure is kind of strange and I'm not sure it's worth salvaging, to be honest. For starters, I recommend moving everything that must happen every frame, like the heads rotating and every check for Blind's HP being less than 0, to a custom waitframe. Basically, create your own function that has all the stuff in it that ends with Ghost_Waitframe and replace every existing waitframe with it.

//Pass the ffc, npc, and angle to this. Maybe other stuff if you need it.
void Blind_Ghost_Waitframe(ffc this, npc n, float angle)
{
     //Head movement/weapon firing goes here.
     if (Ghost_HP <= 0)
     {
          //Stuff to do when Blind dies goes here.
     }
     Ghost_Waitframe(this, n, false, false);
}

Things to keep in mind when creating a custom function: npc variables are effectively global, so your function can change them. Any other variables, however, can't escape the function. If you change them and they aren't global, the main script won't remember the changes. The exception is if you have the function end with a return statement.

int Function(int input)
{
     value = input * 2;
     return value;
}

Using this, you can have the function spit out one number (or any other variable type) based on anything you like.



#118 ywkls

ywkls

    Master

  • Members

Posted 28 June 2015 - 08:32 PM

Well, it took more than a little finagling, but I finally got that script to submit to my will. I didn't actually have to create a custom Waitframe after all! What turned the tide was my realization that the for loop was completely unnecessary to create circular motion. Since it is basically an infinite loop, I could have it's stuff inside the main while loop instead.

 

Once I figured that out, I realized that I just needed to change the order of a few commands and everything else fell into place. 

 

Here's the revised code, soon to be submitted to the database.

Blind the Thief 7.0

I'll probably go back and update my other ghosted enemies to include the Ghost_Waitframe function to avoid any unintended behavior. Thanks to Lejes for helping me understand it!


Edited by ywkls, 06 September 2015 - 10:09 PM.


#119 ywkls

ywkls

    Master

  • Members

Posted 30 June 2015 - 11:37 AM

Some 'proof of concept' code. I don't have the graphics for these yet, but I do have a request out. As soon as I have the graphics, I'll add them to the database along with a test quest.

Big Gohma 1.0

Next up is a variation on that Barinade quest I posted. This is for an enemy similar to Blizzeta from Twilight Princess. It has a central body and for circling defenders. After each one dies, it starts moving move rapidly and the defenders are temporarily invulnerable. Once all the defenders die, the core becomes vulnerable. I don't have graphics for this, but I have requested some. I'm trying to make the core larger than 2 X 2. Once I have graphics, I'll add it to the database.

 

Blizzeta 1.0

I've got some others that I intend to work up, but this will do for now.


Edited by ywkls, 06 September 2015 - 10:13 PM.


#120 ywkls

ywkls

    Master

  • Members

Posted 30 June 2015 - 01:12 PM

More 'proof of concept' code. This creates an Iron Knuckle type of enemy who throws an axe at Link every few seconds. As his HP drops, his speed and the frequency of his axe attacks increases.

Iron Knuckle 1.0

I don't have the sprites for the main enemy, thought I do have the ones for the Axe. I've requested enemy sprites and when I get some I'll add him to the database.


Edited by ywkls, 06 September 2015 - 10:13 PM.



0 user(s) are reading this topic

0 members, 0 guests, 0 anonymous users