PDA

View Full Version : 8-way Multidirectional Shooter Weapon



bigjoe
03-17-2008, 01:29 PM
This is a simple script for a new weapon. It is a spell that shoots a weapon in all cardinal and ordinal directions. It started out just being something to test the new possibility of placing lweapons, but evolved enough for me to think it at least a decent script. Different levels of the weapon can have completely different attributes, thanks to the flexibility offered by internal Item arguments. It's not the best script in the world, but it might give people some ideas. Additionally, it could serve as a sort of lower-level Din's Fire or something.

NOTE: The script refers to it as a "Beam", while it's not necessarily that in effect. I didn't feel like changing every instance of 'beam' just for continuity. :p

NOTE II: Magic consumption is not handled internally to the script. If you want it to drain magic just make the appropriate item do so.

LAST NOTE: I have the projectiles in this script set as magic. You can change that by modifying the value in the CreateLWeapon declarations. I had meant to have this be changeable through an argument, but ran out of them.


Youtube Video of Two Different Levels of the Weapon (http://www.youtube.com/watch?v=TsoErDjrmKM)

import "std.zh"

Declare the following at the global level.



//Multi-Directional Beam Variable Declarations
int item_mdbeam_used = 0; // For detecting if the multi-directional beam is used.
int item_mdbeam_d0 = 0; // These transfers multi-directional beam's D0 - D7 to global handler.
int item_mdbeam_d1 = 0;
int item_mdbeam_d2 = 0;
int item_mdbeam_d3 = 0;
int item_mdbeam_d4 = 0;
int item_mdbeam_d5 = 0;
int item_mdbeam_d6 = 0;
int item_mdbeam_d7 = 0;
int item_mdbeam_a = 0; // Multi-directional beam's internal handler A.

Declare the following as item script. Read comments to know what the Item arguments do. Change item arguments as needed for necessary behaviour.


//##====================================##
//## Multi-Directional Beam Script ##
//## Item Startup Code ##
//## This item will make Link shoot a ##
//## Beam in all 8 Directions. ##
//## Speed varies with each shot. ##
//## ##
//## D0 = Damage Done By Projectiles ##
//## D1 = Amount of Time to Pause ##
//## D2 = Tile that Begins Sequences ##
//## D3 = Number of Frames Per Sequence ##
//## D4 = Animation Speed ##
//## D5 = Color Set ##
//## D6 = Beam Speed ##
//## D7 = Diagonal Beam Speed ##
//## #000 ##
//##====================================##
// Note: D2 begins the graphics needed for each and every different beam.
// D3 adds the number of additional frames to each beam. So if you had D2
// as 400 and D3 as 3, your first beam animation would be 400, 401, 402.
// Second would be 403, 404, 405. And so on.

item script item_mdbeam{
void run(int arg1, int arg2, int arg3, int arg4, int arg5, int arg6, int arg7, int arg8){

if (item_mdbeam_used == 0){

item_mdbeam_d0 = arg1;
item_mdbeam_d1 = arg2;
item_mdbeam_d2 = arg3;
item_mdbeam_d3 = arg4;
item_mdbeam_d4 = arg5;
item_mdbeam_d5 = arg6;
item_mdbeam_d6 = arg7;
item_mdbeam_d7 = arg8;
item_mdbeam_used = 1;
}

}
}

//##====================================##
//## Multi-Directional Beam Script ##
//## End of Item Segment ##
//##====================================##Put the following somewhere in a Global Script.
Note: Be sure to have Waitframe(); at the end of your global script!
Thanks to Gleeok for helping me shorten it!



//##====================================##
//## Multi-Directional Beam Script ##
//## Global Handler ##
//##This segment will make Link shoot a ##
//## Beam in all 8 Directions. ##
//## ##
//##====================================##


if (item_mdbeam_used == 1){
item_mdbeam_a = item_mdbeam_d1;

for(int i; i<8;i++){
lweapon beam3 = Screen->CreateLWeapon(13);
beam3->X = Link->X; beam3->Y = Link->Y; beam3->Z = Link->Z;
beam3->Dir = i;
if(i<4)beam3->Step = item_mdbeam_d6;
else beam3->Step = item_mdbeam_d7;
beam3->Damage = item_mdbeam_d0;
beam3->OriginalTile = item_mdbeam_d2 + (item_mdbeam_d3*i);
beam3->ASpeed = item_mdbeam_d4;
beam3->NumFrames = item_mdbeam_d3;
beam3->Frame = 0;
beam3->FlashCSet = 8;
beam3->CSet = item_mdbeam_d5;
}

item_mdbeam_used = 0;
}


if(item_mdbeam_a > 0){
item_mdbeam_a--;
Link->Action = 3;
Link->Item[250] = 1;

if(Link->Dir == 0)Screen->DrawTile(1, Link->X, Link->Y, 340, 1, 1, 6, 1, 0, 0, 0, 0, 1, 128);

if(Link->Dir == 1)Screen->DrawTile(1, Link->X, Link->Y, 341, 1, 1, 6, 1, 0, 0, 0, 0, 1, 128);

if(Link->Dir == 2)Screen->DrawTile(1, Link->X, Link->Y, 342, 1, 1, 6, 1, 0, 0, 0, 0, 1, 128);

if(Link->Dir == 3)Screen->DrawTile(1, Link->X, Link->Y, 343, 1, 1, 6, 1, 0, 0, 0, 0, 1, 128);


} else {
Link->Item[250] = 0;
if (Link->Action == 3) Link->Action = 0;
}

//##====================================##
//## Multi-Directional Beam Script ##
//## End of Global Segment ##
//##====================================##I don't consider myself to be a veteran scriptor yet, so if some of the more keen scriptors know ways to reduce and optimize this, please share them.

Aegix Drakan
03-17-2008, 01:54 PM
:o Wow...Awesome script....

Good going there!

Gleeok
03-17-2008, 05:49 PM
Hey, cool stuff . Way to go.
And people: You can customize this in a few ways by using the many D arguments. Dont forget we've got 20 brand new Item classes for scripted weapons now! Try these scripts out people!





I don't consider myself to be a veteran scriptor yet, so if some of the more keen scriptors know ways to reduce and optimize this, please share them.

Well it looks fine to me. I like to use copy/paste freindly snippets when using alot of arguments too. You could just cycle it x times in a loop though.


for(int i; i<8;i++){
lweapon beam3 = Screen->CreateLWeapon(13);
beam3->X = Link->X; beam3->Y = Link->Y; beam3->Z = Link->Z;
beam3->Dir = i;
if(i<4)beam3->Step = item_mdbeam_d6;
else beam3->Step = item_mdbeam_d7;
beam3->Damage = item_mdbeam_d0;
beam3->OriginalTile = item_mdbeam_d2 + (item_mdbeam_d3*i);
beam3->ASpeed = item_mdbeam_d4;
beam3->NumFrames = item_mdbeam_d3;
beam3->Frame = 0;
beam3->FlashCSet = 8;
beam3->CSet = item_mdbeam_d5;
}



Like this. That would work fine too.

Joe123
03-17-2008, 05:54 PM
Would that for loop create the 8 weapon effect Gleeok?

I was going to suggest waiting until the next build and using an array.

Russ
03-17-2008, 06:09 PM
I was going to suggest waiting until the next build and using an array.
Say what? The next build has arrays?

Gleeok
03-17-2008, 06:15 PM
Would that for loop create the 8 weapon effect Gleeok?

I was going to suggest waiting until the next build and using an array.

Well of course it would. Hence the:

beam3->Dir = i;

Alternatively you could also just stick this loop in the item script instead of the global script and cut out a whole bunch of extra code that wouldn't need to be declared as global if you did it that way. But really that's just splitting hairs.




Say what? The next build has arrays?

Well...if the next build is ever released that is... :p

Joe123
03-17-2008, 06:31 PM
But doesn't the script only create one lweapon though?

bigjoe
03-17-2008, 06:35 PM
Well it looks fine to me. I like to use copy/paste freindly snippets when using alot of arguments too. You could just cycle it x times in a loop though.


for(int i; i<8;i++){
lweapon beam3 = Screen->CreateLWeapon(13);
beam3->X = Link->X; beam3->Y = Link->Y; beam3->Z = Link->Z;
beam3->Dir = i;
if(i<4)beam3->Step = item_mdbeam_d6;
else beam3->Step = item_mdbeam_d7;
beam3->Damage = item_mdbeam_d0;
beam3->OriginalTile = item_mdbeam_d2 + (item_mdbeam_d3*i);
beam3->ASpeed = item_mdbeam_d4;
beam3->NumFrames = item_mdbeam_d3;
beam3->Frame = 0;
beam3->FlashCSet = 8;
beam3->CSet = item_mdbeam_d5;
}

Like this. That would work fine too.

Thanks man! I was afraid to try using a for loop. All of my attempts to do that before in other scripts have resulted in problems. But seeing how you've executed it(and it works!) I might be less afraid to try them out in the future. I'll stick this in the main segment and credit you for it. Once again, thanks!


But doesn't the script only create one lweapon though?

I guess It looks that way if you don't understand the syntax. The for loop goes through itself 8 times, and as i changes each time, it does the necessary stuff 8 times, creating 8 different weapons.

In the past, I've had trouble with for loops, but it was probably bad math on my part that caused them not to work.

Gleeok
03-17-2008, 07:02 PM
Awesome. Also I've got a few I can post now, (three I think..There's some bugs with the rest so i'm waiting for the new build to come out with the fixes) But my computer sucks something feirce for trying to make vids, which I've learned is the best way to get people to actually check out scripts.

Anyone want to make one?

Their easy to set up, no variables. Just replace the cande, wand, and boomerang with custom item classes 1,2,3. That's it.

It's a lv3 wand, multi-rang!, and flamethrower! I'm making a new thread for them now. Anyone?

Joe123
03-17-2008, 07:16 PM
I'd like to think I do understand the syntax, but maybe I don't :confused:

So the script creates a new weapon called 'beam3' every time the for loops, but surely it should reference them all the same?
Does it derefrence the old one when that happens, and then beam3 just becomes the new weapon?
So if you edited beam3's Vx next frame, it'd only change the last one to be made?

Gleeok
03-17-2008, 07:45 PM
Does it derefrence the old one when that happens, and then beam3 just becomes the new weapon?


I'd hope so.

I'm not sure how it would work in normal C language, but as far as Zscript goes this is a HUGE benefit. It's the only way I can go through every Link and enemy weapon sprite, all the screen enemies' and many ffc cordinates, and check their locations in proximity to eachother based on CSets. Much faster than arrays.

Ugh...anyways I posted some boss scripts at pure that use alot of for loops, so check those out.


Now, I expect people to be using these scripts in quests. I mean c'mon people, it's an 8-way Link fireball! ;)

Joe123
03-17-2008, 07:56 PM
Yeah, I've seen those scripts, I just don't understand how they work >_<

Like that flamethrower script you made.
It's about the only script that simple that I just can't understand.

Gleeok
03-17-2008, 09:07 PM
Hey bigjoe, I just realized that if you change it to eweapon instead of lweapon and changed it to flame, then you just turned any enemy into a fire wizzrobe!





Like that flamethrower script you made.
It's about the only script that simple that I just can't understand.


It's really quite simple. You have a loop like this:


for(int i=Screen->NumNPCs();i>1;i--){

Now lets assume there are 100 enemies on the screen, So i=100 right? As the loop runs down to 1 (but not 1!) you've just run through every number that is a screen enemy, exept 1. So Screen enemies 2-100 could be pointed to by adding something like this inside the loop:


npc enemy = Screen->LoadNPC(i);

From here we can do whatever we want to each of those 99 NPCs on the screen every frame. ...Like this:



for(int i=Screen->NumNPCs();i>1;i--){
npc enemy = Screen->LoadNPC(i);
enemy->HP=100;
}

Now Link is gonna find it pretty hard to kill those enemies if they keep regenerating themselves.

Make sense.

Joe123
03-18-2008, 03:47 AM
Oh!

Well that makes more sense.


I couldn't work out how you were referencing so many enemies with just one pointer.