Jump to content

Photo

Creating custom swords and wands


  • Please log in to reply
56 replies to this topic

#16 Binx

Binx

    Formerly Lineas

  • Members
  • Real Name:Brian
  • Location:Lancaster, CA

Posted 30 July 2013 - 07:24 PM

Are you kidding? I have VERY little experience (well, at least with scripting, I know the hardcoded stuff pretty well), so dumb it down as much as you want, lol. Anyways it looks like there would be an issue getting enemies to only work with one type of magic, unless they're all custom item classes,and even then, it looks like the enemy defenses treat all scripted weapons the same.



#17 Orithan

Orithan

    Studying Scientist - Commission from Silvixen

  • Members
  • Location:Australia

Posted 31 July 2013 - 01:39 AM

Ok, then.... Now i just have to figure out how in the hell I'm going to make x2 and x1/2 damage attributes for certain weapons on monsters.... And the custom triggers, cuz I need each of the swords to only work on one trigger type. And how I'm going to make multiple levels of each elemental type sword, cuz I wanted upgrading the elemental items to be a big part of the game, as well.

 

For the defenses, I made a function that emulates the built-in defenses so that script weapons can use them to mimick default weapons when I was working on a scripted bomb. Hope this helps, especially with the Fire element.

 

void EmulateDefenses(lweapon wpn, npc nme, int def){ //The start of the function. The variables are the LWeapon to use, the npc is has just collided with and the defense you want to imitate.
    if(nme->Defense[def] == NPCDT_HALFDAMAGE){ //Halves the LWeapon's damage.
        wpn->Damage /= 2;
    }
    else if(nme->Defense[def] == NPCDT_QUARTERDAMAGE){ //Quarters the LWeapon's damage
        wpn->Damage /= 4;
    }
    else if(nme->Defense[def] == NPCDT_STUN){ //Stuns the NPC
        wpn->Damage = 0;
        nme->Stun = 256;
    }
    else if(nme->Defense[def] == NPCDT_STUNORBLOCK){ //Stuns or blocks the LWeapon
        if(wpn->Damage >= 2){
            wpn->Damage = 0;
            nme->Stun = 256;
        }
        else{
            Remove(wpn);
            Game->PlaySound(SFX_CLINK);
        }
    }
    else if(nme->Defense[def] == NPCDT_STUNORIGNORE){ //Stun or Ignore the NPC.
        if(wpn->Damage >= 2){
            wpn->Damage = 0;
            nme->Stun = 256;
        }
        else{
            Remove(wpn);
        }
    }
    else if(nme->Defense[def] == NPCDT_BLOCK1){ //Block if the LWeapon does 2 or less damage.
        if(wpn->Damage < 2){
            Remove(wpn);
            Game->PlaySound(SFX_CLINK);
        }
    }
    else if(nme->Defense[def] == NPCDT_BLOCK2){ //Block if the LWeapon does 4 or less damage.
        if(wpn->Damage < 4){
            Remove(wpn);
            Game->PlaySound(SFX_CLINK);
        }
    }
    else if(nme->Defense[def] == NPCDT_BLOCK4){ //Block if the LWeapon does 8 or less damage
        if(wpn->Damage < 8){
            Remove(wpn);
            Game->PlaySound(SFX_CLINK);
        }
    }
    else if(nme->Defense[def] == NPCDT_BLOCK6){ //Block if the LWeapon does 12 or less damage
        if(wpn->Damage < 12){
            Remove(wpn);
            Game->PlaySound(SFX_CLINK);
        }
    }
    else if(nme->Defense[def] == NPCDT_BLOCK8){ //Block if the LWeapon does 16 or less damage
        if(wpn->Damage < 16){
            Remove(wpn);
            Game->PlaySound(SFX_CLINK);
        }
    }
    else if(nme->Defense[def] == NPCDT_BLOCK){ //Blocks the LWeapon outright.
        Remove(wpn);
        Game->PlaySound(SFX_CLINK);
    }
    else if(nme->Defense[def] == NPCDT_IGNORE1){ //The LWeapon ignores the NPC if it would do 2 or less damage.
        if(wpn->Damage < 2){
            Remove(wpn);
        }
    }
    else if(nme->Defense[def] == NPCDT_IGNORE){ //The LWeapon outright ignores the NPC.
        Remove(wpn);
    }
    else if(nme->Defense[def] == NPCDT_ONEHITKILL){ //The LWeapon OHKOs the NPC.
        wpn->Damage = nme->HP;
    }
}

 

The damage modifications can be easily done provided that the Script Weapon defense are set to "Normal" on all enemies. This will also mean that it would be useless on built-in Diggdoggers and Dodongoes. At the moment, I have no idea to add in new defenses to enemies without setting them all individually so you are out of luck here with me.



#18 Timelord

Timelord

    The Timelord

  • Banned
  • Location:Prydon Academy

Posted 31 July 2013 - 01:48 AM

Here's a bit of a more flexible, cleaner and commented version of your script Aevin:
 
/////////////////////////
/// Magic Projectile ///////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////
/// D0: MP cost per use.                                          ///
/// D1: Speed that Subweapon Travels across screen; suggest 240.  ///
/// D2: Amount of Damage that Subweapon Deals to Enemies.         ///
/// D3: Sprite used by Subweapon; select from:                    ///
///            Quest->Graphics->Sprites->WeaponsMisc.             ///   
/// D4: Maximum number of projectiles allowed at once.            ///
/// D5: Error Sound Effects.                                      ///
/// D6: Item Sound Effects.  Select sounds from:                  ///
///            Quest->Audio->SFX Data                             ///   
/// D7: Delay before Link can use item again.                     ///     
/////////////////////////////////////////////////////////////////////


item script MagicProjectile
{
    void run(int magicCost, int speed, int power, int spriteUsed, maxProjectiles, int SXF_ERROR, int SFX_ITEM, int nouse)
    {
    if(Game->Counter[CR_MAGIC] >= (magicCost && NumLWeaponsOf(LW_MAGIC) <= maxProjectiles) //Fill in the numbers for magic consumption and number of projectiles allowed on screen
        {
        Game->Counter[CR_MAGIC] -= magicCost; //fill in the magic consumption here as well
        lweapon magic = Screen->CreateLWeapon(LW_MAGIC);
        arrow->UseSprite(spriteUsed); // the number of the sprite used for the projectile. Use two tiles, the first for up/down, the second for left/right
        magic->X = Link->X; //Find Link's Position X
        magic->Y = Link->Y; //Find Link's Position Y
        magic->Dir = Link->Dir; //Find the Direction that Link is facing.
        magic->Step = speed; // the speed the projectile travels
        magic->Damage = power; //the damage the projectile will do
        Game->PlaySound(SFX_ITEM); // the sound effect for the weapon
		Link->ItemJinx = (nouse * 1); //Set delay between firing. Change multiplier if desired, but set base in argument D7.
        if(Link->Dir == DIR_DOWN) //If Link is facing down...
            {
            magic->Flip = 2; //Change direction of spriteUsed to down.
            }
        if(Link->Dir == DIR_RIGHT) //If Link is facing right.
            {
            magic->Tile += 1; //Use next tile as well.
            }
        if(Link->Dir == DIR_LEFT)
            {
            magic->Tile += 1; //If Link is facing left.
            magic->Flip = 1; //Flip spriteUsed tile and use next tile as well.
            }
		
        }
        
		else{
    Game->PlaySound(SFX_ERROR); //If out of MP, play ERROR SOund Effects.
    }
    }
}
This version uses arguments to set the item functions, rather than hard-coding them. The part that I don't understand is why you are using a second tile for the sprite on left and right directions where a flip would normally work.

Here is an alternate, in case that version fails to work when MP is exactly equal to the cost specified:
 
/////////////////////////
/// Magic Propjectile ///////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////
/// D0: MP cost per use.                                          ///
/// D1: Speed that Subweapon Travels across screen; suggest 240.  ///
/// D2: Amount of Damage that Subweapon Deals to Enemies.         ///
/// D3: Sprite used by Subweapon; select from:                    ///
///            Quest->Graphics->Sprites->WeaponsMisc.             ///   
/// D4: Maximum number of projectiles allowed at once.            ///
/// D5: Error Sound Effects.                                      ///
/// D6: Item Sound Effects.  Select sounds from:                  ///
///            Quest->Audio->SFX Data                             ///   
/// D7: Delay before Link can use item again.                     ///     
/////////////////////////////////////////////////////////////////////


item script MagicProjectile
{
    void run(int magicCost, int speed, int power, int spriteUsed, maxProjectiles, int SXF_ERROR, int SFX_ITEM, int nouse)
    {
    if(Game->Counter[CR_MAGIC] >= (magicCost -1) && NumLWeaponsOf(LW_MAGIC) <= maxProjectiles) //Fill in the numbers for magic consumption and number of projectiles allowed on screen
        {
        Game->Counter[CR_MAGIC] -= magicCost; //fill in the magic consumption here as well
        lweapon magic = Screen->CreateLWeapon(LW_MAGIC);
        arrow->UseSprite(spriteUsed); // the number of the sprite used for the projectile. Use two tiles, the first for up/down, the second for left/right
        magic->X = Link->X; //Find Link's Position X
        magic->Y = Link->Y; //Find Link's Position Y
        magic->Dir = Link->Dir; //Find the Direction that Link is facing.
        magic->Step = speed; // the speed the projectile travels
        magic->Damage = power; //the damage the projectile will do
        Game->PlaySound(SFX_ITEM); // the sound effect for the weapon
		Link->ItemJinx = (nouse * 1); //Set delay between firing. Change multiplier if desired, but set base in argument D7.
        if(Link->Dir == DIR_DOWN) //If Link is facing down...
            {
            magic->Flip = 2; //Change direction of spriteUsed to down.
            }
        if(Link->Dir == DIR_RIGHT) //If Link is facing right.
            {
            magic->Tile += 1; //Use next tile as well.
            }
        if(Link->Dir == DIR_LEFT)
            {
            magic->Tile += 1; //If Link is facing left.
            magic->Flip = 1; //Flip spriteUsed tile and use next tile as well.
            }
		
        }
        
		else{
    Game->PlaySound(SFX_ERROR); //If out of MP, play ERROR Sound Effects.
    }
    }
}

Edited by ZoriaRPG, 31 July 2013 - 01:57 AM.


#19 Binx

Binx

    Formerly Lineas

  • Members
  • Real Name:Brian
  • Location:Lancaster, CA

Posted 31 July 2013 - 01:49 AM

For the defenses, I made a function that emulates the built-in defenses so that script weapons can use them to mimick default weapons when I was working on a scripted bomb. Hope this helps, especially with the Fire element.

 

 

void EmulateDefenses(lweapon wpn, npc nme, int def){ //The start of the function. The variables are the LWeapon to use, the npc is has just collided with and the defense you want to imitate.
    if(nme->Defense[def] == NPCDT_HALFDAMAGE){ //Halves the LWeapon's damage.
        wpn->Damage /= 2;
    }
    else if(nme->Defense[def] == NPCDT_QUARTERDAMAGE){ //Quarters the LWeapon's damage
        wpn->Damage /= 4;
    }
    else if(nme->Defense[def] == NPCDT_STUN){ //Stuns the NPC
        wpn->Damage = 0;
        nme->Stun = 256;
    }
    else if(nme->Defense[def] == NPCDT_STUNORBLOCK){ //Stuns or blocks the LWeapon
        if(wpn->Damage >= 2){
            wpn->Damage = 0;
            nme->Stun = 256;
        }
        else{
            Remove(wpn);
            Game->PlaySound(SFX_CLINK);
        }
    }
    else if(nme->Defense[def] == NPCDT_STUNORIGNORE){ //Stun or Ignore the NPC.
        if(wpn->Damage >= 2){
            wpn->Damage = 0;
            nme->Stun = 256;
        }
        else{
            Remove(wpn);
        }
    }
    else if(nme->Defense[def] == NPCDT_BLOCK1){ //Block if the LWeapon does 2 or less damage.
        if(wpn->Damage < 2){
            Remove(wpn);
            Game->PlaySound(SFX_CLINK);
        }
    }
    else if(nme->Defense[def] == NPCDT_BLOCK2){ //Block if the LWeapon does 4 or less damage.
        if(wpn->Damage < 4){
            Remove(wpn);
            Game->PlaySound(SFX_CLINK);
        }
    }
    else if(nme->Defense[def] == NPCDT_BLOCK4){ //Block if the LWeapon does 8 or less damage
        if(wpn->Damage < 8){
            Remove(wpn);
            Game->PlaySound(SFX_CLINK);
        }
    }
    else if(nme->Defense[def] == NPCDT_BLOCK6){ //Block if the LWeapon does 12 or less damage
        if(wpn->Damage < 12){
            Remove(wpn);
            Game->PlaySound(SFX_CLINK);
        }
    }
    else if(nme->Defense[def] == NPCDT_BLOCK8){ //Block if the LWeapon does 16 or less damage
        if(wpn->Damage < 16){
            Remove(wpn);
            Game->PlaySound(SFX_CLINK);
        }
    }
    else if(nme->Defense[def] == NPCDT_BLOCK){ //Blocks the LWeapon outright.
        Remove(wpn);
        Game->PlaySound(SFX_CLINK);
    }
    else if(nme->Defense[def] == NPCDT_IGNORE1){ //The LWeapon ignores the NPC if it would do 2 or less damage.
        if(wpn->Damage < 2){
            Remove(wpn);
        }
    }
    else if(nme->Defense[def] == NPCDT_IGNORE){ //The LWeapon outright ignores the NPC.
        Remove(wpn);
    }
    else if(nme->Defense[def] == NPCDT_ONEHITKILL){ //The LWeapon OHKOs the NPC.
        wpn->Damage = nme->HP;
    }
}

 

The damage modifications can be easily done provided that the Script Weapon defense are set to "Normal" on all enemies. This will also mean that it would be useless on built-in Diggdoggers and Dodongoes. At the moment, I have no idea to add in new defenses to enemies without setting them all individually so you are out of luck here with me.

 

 

 

 

So, if I'm understanding correctly (Sorry if these are dumb or obvious questions, I like to double and triple check and confirm everything, I just learn better that way), I would set all of this as part of the item script and list all of the enemies that it doesn't deal 1x damage to as part of the associated if statement (like 2x or 1/2 or block), so it would all be stored in the weapon data, rather than the enemies?


Edited by Lineas, 31 July 2013 - 01:50 AM.


#20 Binx

Binx

    Formerly Lineas

  • Members
  • Real Name:Brian
  • Location:Lancaster, CA

Posted 31 July 2013 - 01:52 AM

Here's a bit of a more flexible, cleaner and commented version of your script Aevin:
 

/////////////////////////
/// Magic Propjectile ///////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////
/// D0: MP cost per use.                                          ///
/// D1: Speed that Subweapon Travels across screen; suggest 240.  ///
/// D2: Amount of Damage that Subweapon Deals to Enemies.         ///
/// D3: Sprite used by Subweapon; select from:                    ///
///            Quest->Graphics->Sprites->WeaponsMisc.             ///   
/// D4: Maximum number of projectiles allowed at once.            ///
/// D5: Error Sound Effects.                                      ///
/// D6: Item Sound Effects.  Select sounds from:                  ///
///            Quest->Audio->SFX Data                             ///   
/// D7: Delay before Link can use item again.                     ///     
/////////////////////////////////////////////////////////////////////


item script MagicProjectile
{
    void run(int magicCost, int speed, int power, int spriteUsed, maxProjectiles, int SXF_ERROR, int SFX_ITEM, int nouse)
    {
    if(Game->Counter[CR_MAGIC] >= magicCost && NumLWeaponsOf(LW_MAGIC) <= maxProjectiles) //Fill in the numbers for magic consumption and number of projectiles allowed on screen
        {
        Game->Counter[CR_MAGIC] -= magicCost; //fill in the magic consumption here as well
        lweapon magic = Screen->CreateLWeapon(LW_MAGIC);
        arrow->UseSprite(spriteUsed); // the number of the sprite used for the projectile. Use two tiles, the first for up/down, the second for left/right
        magic->X = Link->X; //Find Link's Position X
        magic->Y = Link->Y; //Find Link's Position Y
        magic->Dir = Link->Dir; //Find the Direction that Link is facing.
        magic->Step = speed; // the speed the projectile travels
        magic->Damage = power; //the damage the projectile will do
        Game->PlaySound(SFX_ITEM); // the sound effect for the weapon
		Link->ItemJinx = (nouse * 1); //Set delay between firing. Change multiplier if desired, but set base in argument D7.
        if(Link->Dir == DIR_DOWN) //If Link is facing down...
            {
            magic->Flip = 2; //Change direction of spriteUsed to down.
            }
        if(Link->Dir == DIR_RIGHT) //If Link is facing right.
            {
            magic->Tile += 1; //Use next tile as well.
            }
        if(Link->Dir == DIR_LEFT)
            {
            magic->Tile += 1; //If Link is facing left.
            magic->Flip = 1; //Flip spriteUsed tile and use next tile as well.
            }
		
        }
        
		else{
    Game->PlaySound(SFX_ERROR); //If out of MP, play ERROR Sound Effects.
    }
    }
}
This version uses arguments to set the item functions, rather than hard-coding them.

 

So, this is basically a generic script that you just use arguments, so you'd only need one script, and you could just adjust the arguments to get different effects?



#21 Aevin

Aevin

  • Members
  • Pronouns:He / Him
  • Location:Oregon

Posted 31 July 2013 - 02:32 AM

Here's a bit of a more flexible, cleaner and commented version of your script Aevin:

It's funny you mention it, because I had no idea how to use arguments for scripts until last night, when I had a sudden inspiration and changed the script to include them myself, combining the three scripts I was using for my elemental arrows into one. (I was so proud of myself, too ...) It's definitely educational to see how a more skilled scripter does it. I would like to point out that it's just an example I made for my personal use, and I really didn't want a firing delay or error sound, so I didn't include them.  As for the tile ...  I just can't make it clear enough that I'm an amateur, there are errors abound, and no one else was replying here, so I did what I could to help. In any case, thanks for the education. :)



#22 Timelord

Timelord

    The Timelord

  • Banned
  • Location:Prydon Academy

Posted 31 July 2013 - 06:46 AM

@ Lineas : Yes, that script is set up to pass whatever arguments you set in the item editor (where you assign this to the item's active script slot) to ZASM for interpretation. That means that if you want five wands, each with theifr own effects, you can assign them all based on one script. In fact, you can make a script that assigns the kind of LWeapon as an argument, for an entirely generic LWeapon script.
 
That means you lose one argument out of eight possible, and I often find that I need more than those given, but as an example, you could do this (untested) for a very generic LWeapon script that you customise in the item arguments:
 

/////////////////////////
/// Generic LWeapon ///////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////
/// D0: MP or Counter cost per use.                                     ///
/// D1: Speed that Subweapon Travels across screen; suggest 240.        ///
/// D2: Amount of Damage that Subweapon Deals to Enemies.               ///
/// D3: Sprite used by Subweapon; select from:                          ///
///            Quest->Graphics->Sprites->WeaponsMisc.                   ///   
/// D4: The counter to use for this item (numeric from std_constants.zh ///
/// D5: Error Sound Effects.                                            ///
/// D6: Item Sound Effects.  Select sounds from:                        ///
///            Quest->Audio->SFX Data                                   ///   
/// D7: The kind of LWeapon to generate (numeric) from std_constants.zh ///     
/////////////////////////////////////////////////////////////////////////// 


item script ProjectileLWeapon
{
    void run(int Cost, int speed, int power, int spriteUsed, CountertoUse, int SXF_ERROR, int SFX_ITEM, int lType)
    {
    if(Game->Counter[CountertoUse] >= (Cost - 1) //If the player has enough MP based on amount set in D0 MP cost.
        {
        Game->Counter[CountertoUse] -= Cost; //Select a counter from std_constants.zh and set the value for the counter in D, and the cost in D0.
        lweapon lw = Screen->CreateLWeapon(lType); //Set (numerical) type of LWeapon to generate as argument D7 (from std_constants.zh)
        arrow->UseSprite(spriteUsed); // the number of the sprite used for the projectile. Use two tiles, the first for up/down, the second for left/right
        lw->X = Link->X; //Find Link's Position X
        lw->Y = Link->Y; //Find Link's Position Y
        lw->Dir = Link->Dir; //Find the Direction that Link is facing.
        lw->Step = speed; // the speed the projectile travels
        lw->Damage = power; //the damage the projectile will do
        Game->PlaySound(SFX_ITEM); // the sound effect for the weapon
        if(Link->Dir == DIR_DOWN) //If Link is facing down...
            {
            lw->Flip = 2; //Change direction of spriteUsed to down.
            }
        if(Link->Dir == DIR_RIGHT) //If Link is facing right.
            {
            lw->Tile += 1; //Use next tile as well.
            }
        if(Link->Dir == DIR_LEFT)
            {
            lw->Tile += 1; //If Link is facing left.
            lw->Flip = 1; //Flip spriteUsed tile and use next tile as well.
            }
		
        }
        
		else{
    Game->PlaySound(SFX_ERROR); //If out of MP, play ERROR Sound Effects.
    }
    }
}

 
@Aevin: Don't let this deceive you into thinking I'm some sort of wizard; if I were, I;d hardly be likely to be the one asking routine questions on the functions of ZScript. I tend to learn best with functional examples, so the documentation provided is only somewhat useful. When I see something in use, so that I can see how to use it properly, I usually remember it, or at least have a reference to fall back upon. That's how programming languages were taught in my day... I've no idea how things are done now, and I never paid much attention to C, other than in terms of physics constants.
 
I just noticed that you hard-coded what could be variables that would make this a much more flexible script, and changed those to be assigned in attributes: I've made some of my scripts hard-coded for the games that I'm working on at present, but that is usually a mistake. The fewer scripts that I need to rely on at one time, the less I have to debug. The only hassle is that I have to remember which argument was assigned to what ability for each script, which is why I put that huge banner at the top of all of them (unless they have no arguments to set). It's as much for me to remember what is going on as it is to let others use it. 8)
 
I wish I could make some kind of use out of the address values as well, as having a maximum of eight arguments is a bit limiting. If I has sixteen, i think I would be fine forever, but a couple scripts that I put together either required one hardcoded value, or more arguments, and as the latter is impossible, it meant that some script duplication was mandatory for me.
 
As to SFX, I find it useful for items that can error out to provide some kind of feedback to the player, as this way the player both knows that the game is not broken, and has a reminder of 'Hey, genius, you ran out of XYZ.' when playing the game, which when you have a plethora of counter-based items, is handy. I usually have one generic SFX ERROR in a given game, or possibly two or three set in the environmental constants, but this allows a somewhat lazier method, to assign them within a scripted item (which means you can change them without recompiling).



#23 Binx

Binx

    Formerly Lineas

  • Members
  • Real Name:Brian
  • Location:Lancaster, CA

Posted 31 July 2013 - 11:04 AM

 

@ Lineas : Yes, that script is set up to pass whatever arguments you set in the item editor (where you assign this to the item's active script slot) to ZASM for interpretation. That means that if you want five wands, each with theifr own effects, you can assign them all based on one script. In fact, you can make a script that assigns the kind of LWeapon as an argument, for an entirely generic LWeapon script.

 Ah, ok, I see what you're doing here. Now this creates a generic projectile without a melee attack, correct? So, more like the bow than the wand, for example? Would this item script be placed only on a custom itemclass or could it be used to change the projectile of an existing weapon type (like making a sword use LW_MAGIC, or custom elemental magic)?

 

 

 I tend to learn best with functional examples, so the documentation provided is only somewhat useful. When I see something in use, so that I can see how to use it properly, I usually remember it, or at least have a reference to fall back upon. 

 ^This is exactly how I work. I never learned C, or any kind of programming language, and while the tutorials help a lot, I just don't tend to grasp it until I see the principles used for something more specific. Hence why I always end up asking about every little detail, so that I'll remember how to use it (and more importantly, alter it to do other things).


Edited by Lineas, 31 July 2013 - 04:53 PM.


#24 Timelord

Timelord

    The Timelord

  • Banned
  • Location:Prydon Academy

Posted 01 August 2013 - 12:36 AM

Ah, ok, I see what you're doing here. Now this creates a generic projectile without a melee attack, correct? So, more like the bow than the wand, for example? Would this item script be placed only on a custom itemclass or could it be used to change the projectile of an existing weapon type (like making a sword use LW_MAGIC, or custom elemental magic)?

 

You could use the scripts on a custom item class or a zzXXX item class, set as the action script, or attach them to an existing item as an action script. I you attach them to an existing item, they add to what it does; thus, on a sword, the sword would still act as a sword, and do the script functions as well. If you use them on a generic item class, then that item class does what the script tells ZASM to do with it.

 

You can also attach them to items that normally have no active use, such as shields, or other items, if you want to play about with it. This can be useful if you need your script to rely on an item's Misc Attribues, as custom and zz class items have no assignable misc.. attributes in the editor--I haven;t any idea why--which give you some additional script flexibility later, especially or global scripts that affect items.

 

Anyhow, the first script makes only magic projectiles, but the one I posted yesterday could make projectiles in magic, sparkle, arrow, swordbeam, etc. that you can set in the item script attributes.It also allows you to assign the item counter in the script attributes, and a custom amount to deplete the counter, as well as item power, and other useful stuff, at the sacrifice of some other functions, such as nouse, and maxProjectiles in this example. This item can ire of shots constantly, depleting a counter.

 

Of course, you can add a manual override int he script to force it to fire more slowly, or to limit the maximum number of shots on the screen at once; or you could set the maximum number o LWeapons in your active global script, and affect all LWeapons, or specific kinds of LWeapons to a maximum on-screen at any given time for the entire game. When you want something to affect the whole game, continually, it has to be in the global active script, in the while(true) loop.

 

I still think that a for command should allow me to do so or a duration without being in the global script, but I may be wrong. :?



#25 Binx

Binx

    Formerly Lineas

  • Members
  • Real Name:Brian
  • Location:Lancaster, CA

Posted 01 August 2013 - 01:07 AM

You could use the scripts on a custom item class or a zzXXX item class, set as the action script, or attach them to an existing item as an action script. I you attach them to an existing item, they add to what it does; thus, on a sword, the sword would still act as a sword, and do the script functions as well. If you use them on a generic item class, then that item class does what the script tells ZASM to do with it.

 

You can also attach them to items that normally have no active use, such as shields, or other items, if you want to play about with it. This can be useful if you need your script to rely on an item's Misc Attribues, as custom and zz class items have no assignable misc.. attributes in the editor--I haven;t any idea why--which give you some additional script flexibility later, especially or global scripts that affect items.

 

Anyhow, the first script makes only magic projectiles, but the one I posted yesterday could make projectiles in magic, sparkle, arrow, swordbeam, etc. that you can set in the item script attributes.It also allows you to assign the item counter in the script attributes, and a custom amount to deplete the counter, as well as item power, and other useful stuff, at the sacrifice of some other functions, such as nouse, and maxProjectiles in this example. This item can ire of shots constantly, depleting a counter.

 

Of course, you can add a manual override int he script to force it to fire more slowly, or to limit the maximum number of shots on the screen at once; or you could set the maximum number o LWeapons in your active global script, and affect all LWeapons, or specific kinds of LWeapons to a maximum on-screen at any given time for the entire game. When you want something to affect the whole game, continually, it has to be in the global active script, in the while(true) loop.

 

I still think that a for command should allow me to do so or a duration without being in the global script, but I may be wrong. :?

 

 

Ok, this is very interesting, so I, theoretically, at least, could make a sword, turn off the beam, attach this script and it would fire the projectile when I swing the sword, yes? I guess the next step, then, would be learning how to make use of the "LW_SCRIPT" items and make some custom triggers. Thanks :) This'll make a great workaround for my quest :).



#26 Timelord

Timelord

    The Timelord

  • Banned
  • Location:Prydon Academy

Posted 01 August 2013 - 03:49 AM

Yes, indeed that should work perfectly. I also need to learn scripted triggers, as merely triggering all screen->secrets is problematic if you have more than one trigger per screen.

 

One of my next objectives is to make a whip weapon, that can hit slash combos. (My hope is that this should be as easy as setting the hitbox to be two tiles wide/high and making the sprite with (LW_SWORD) as its lweapon type...)


Edited by ZoriaRPG, 01 August 2013 - 03:51 AM.


#27 Binx

Binx

    Formerly Lineas

  • Members
  • Real Name:Brian
  • Location:Lancaster, CA

Posted 01 August 2013 - 04:03 AM

Well, that SOUNDS like it should work, (The whip idea, I mean) at least? My main thing is just that I have too many damned swords with different abilities, so I need triggers for fire, water, forest, ice, wind, earth, light, shadow and spirit, but there are only 4 built-in sword triggers (Otherwise, I think I'd just take Aevin's advice and use combination sword beam trigger and block flags, it wouldn't be quite as pretty, but it would be functional.)


Edited by Lineas, 01 August 2013 - 04:08 AM.


#28 Timelord

Timelord

    The Timelord

  • Banned
  • Location:Prydon Academy

Posted 01 August 2013 - 05:45 AM

I know that you can use the script triggers to cover that; I merely don;t have enough information to tell you how to do it, as I'ven;t seen a script in use that uses them in that way.

 

I expect that you can set your weapons to use a specific script trigger, and then you would need a global script that does something when the game encounters that trigger, and then merely use combos with that script trigger as their combo flag or type.

 

Using block flags isn't the way to go i you want specific item to set off specific events, as you'll end up with some triggers that can be activated by multiple items, making it very messy in the end. I would love to see a simple, example script for scripted triggers, as I could then make even more progress on what I'm doing. (I think that an FFC with that kind of script attached would be very useful to me as a triggered event, for I could put it anywhere.)

 

I'll have to check is there are any scripts that are designed to use the scripted trigger flags, so that I know how to call for that in functions and commands. (I also need to read more ghosting scripts, as I do not yet know how to make events happen when a ghosted enemy dies.)

 

Alucard wants enemies that explode (and do damage) on death, that are stationary. I thought that the enemy editor and some clever no-enemies and solidified FFCs would make that work, but no soap there... I need to script the enemy with ghost.zh, and make it explode on death, with the explosion doing eweapon damage, and producing a possible drop. I'm also curious i I can negate the bounce-back hit-detection, so that Link isn't hit (bounced, caused to flicker, and making a sound) by enemies with 0 attack power / damage when he touches them.



#29 Binx

Binx

    Formerly Lineas

  • Members
  • Real Name:Brian
  • Location:Lancaster, CA

Posted 01 August 2013 - 09:30 AM

Yeah, but messy or not, I may have no choice on the block flags. There's only 5 scripted triggers in game ( So, no matter what, I'm boned, lol), and I'm already using two for hole and lava combos, so I have three left. Using enemies as triggers isn't viable because I lose the ability to have enemies on the same screen as the triggers. I might have to do it anyways, though, cuz I think even WITH using block flags and the regular sword beam triggers (and I suppose I could actually use two of the sword triggers, as well, but then the projectiles wouldn't be able to activate them), AND the s-bomb, fire and magic triggers (if I can even get any of those to work with the projectiles) It'll only give me a total of 9, and I have 11 swords in game. So, yeah, messy or not, unless I can learn to make a multi-purpose trigger that I can alter with arguments (And actually, that would be a good idea if it's possible, I wonder if you could make an FFC that acts like a flag/trigger, that you could then use arguments to decide which weapon or weapon class triggers it.... Cuz then I could just use the one and alter it around), I'm kinda stuck with kinda having to improvise.

 

As far as ghosted enemies go, I haven't the foggiest. Ghost.zh scares me.


Edited by Lineas, 01 August 2013 - 09:31 AM.


#30 Timelord

Timelord

    The Timelord

  • Banned
  • Location:Prydon Academy

Posted 01 August 2013 - 12:33 PM

I can't say with certainty, but if your use an FFC script for the trigger, you may be able to use the arguments for that to make it work.
 
I tested my scripts from this post and fixed a few errors. here is a new set of scripts that you may find useful; all tested with DEMO. Try the Rod of Dragonfire for the Generic LWeapon item script, and the Bolt! item for the BoltSpell item and FlashScreen FFC scripts.
 

const int ThunderSFX = 0; //Set from Quest->Audio->SFX Data 
const int SFX_ERROR = 0; //Set from Quest->Audio->SFX Data 


/////////////////////////
/// Magic Projectile ///////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////
/// D0: MP cost per use.                                          ///
/// D1: Speed that Subweapon Travels across screen; suggest 240.  ///
/// D2: Amount of Damage that Subweapon Deals to Enemies.         ///
/// D3: Sprite used by Subweapon; select from:                    ///
///            Quest->Graphics->Sprites->WeaponsMisc.             ///   
/// D4: Maximum number of projectiles allowed at once.            ///
/// D5: Error Sound Effects.                                      ///
/// D6: Item Sound Effects.  Select sounds from:                  ///
///            Quest->Audio->SFX Data                             ///   
/// D7: Delay before Link can use item again.                     ///     
/////////////////////////////////////////////////////////////////////


item script MagicProjectile
{
    void run(int magicCost, int speed, int power, int spriteUsed, int maxProjectiles, int SXF_ERROR, int SFX_ITEM, int nouse)
    {
    if (Game->Counter[CR_MAGIC] > magicCost && NumLWeaponsOf(LW_MAGIC) < maxProjectiles) //Fill in the numbers for magic consumption and number of projectiles allowed on screen
        {
        Game->Counter[CR_MAGIC] -= magicCost; //fill in the magic consumption here as well
        lweapon magic = Screen->CreateLWeapon(LW_MAGIC);
        magic->UseSprite(spriteUsed); // the number of the sprite used for the projectile. Use two tiles, the first for up/down, the second for left/right
        magic->X = Link->X; //Find Link's Position X
        magic->Y = Link->Y; //Find Link's Position Y
        magic->Dir = Link->Dir; //Find the Direction that Link is facing.
        magic->Step = speed; // the speed the projectile travels
        magic->Damage = power; //the damage the projectile will do
        Game->PlaySound(SFX_ITEM); // the sound effect for the weapon
		Link->ItemJinx = (nouse * 1); //Set delay between firing. Change multiplier if desired, but set base in argument D7.
        if(Link->Dir == DIR_DOWN) //If Link is facing down...
            {
            magic->Flip = 2; //Change direction of spriteUsed to down.
            }
        if(Link->Dir == DIR_RIGHT) //If Link is facing right.
            {
            magic->Tile += 1; //Use next tile as well.
            }
        if(Link->Dir == DIR_LEFT)
            {
            magic->Tile += 1; //If Link is facing left.
            magic->Flip = 1; //Flip spriteUsed tile and use next tile as well.
            }
		
        }
        
		else{
    Game->PlaySound(SFX_ERROR); //If out of MP, play ERROR SOund Effects.
    }
    }
}

/////////////////////////
/// Generic LWeapon ///////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////
/// D0: MP or Counter cost per use.                                     ///
/// D1: Speed that Subweapon Travels across screen; suggest 240.        ///
/// D2: Amount of Damage that Subweapon Deals to Enemies.               ///
/// D3: Sprite used by Subweapon; select from:                          ///
///            Quest->Graphics->Sprites->WeaponsMisc.                   ///   
/// D4: The counter to use for this item (numeric from std_constants.zh ///
/// D5: Error Sound Effects.                                            ///
/// D6: Item Sound Effects.  Select sounds from:                        ///
///            Quest->Audio->SFX Data                                   ///   
/// D7: The kind of LWeapon to generate (numeric) from std_constants.zh ///     
/////////////////////////////////////////////////////////////////////////// 


item script ProjectileLWeapon{
    void run(int Cost, int speed, int power, int spriteUsed, int CountertoUse, int SXF_ERROR, int SFX_ITEM, int lType){
    if ( Game->Counter[CountertoUse] > Cost ) //If the player has enough MP based on amount set in D0 MP cost.
        {
        Game->Counter[CountertoUse] -= Cost; //Select a counter from std_constants.zh and set the value for the counter in D, and the cost in D0.
        lweapon lw = Screen->CreateLWeapon(lType); //Set (numerical) type of LWeapon to generate as argument D7 (from std_constants.zh)
        lw->UseSprite(spriteUsed); // the number of the sprite used for the projectile. Use two tiles, the first for up/down, the second for left/right
        lw->X = Link->X; //Find Link's Position X
        lw->Y = Link->Y; //Find Link's Position Y
        lw->Dir = Link->Dir; //Find the Direction that Link is facing.
        lw->Step = speed; // the speed the projectile travels
        lw->Damage = power; //the damage the projectile will do
        Game->PlaySound(SFX_ITEM); // the sound effect for the weapon
        if(Link->Dir == DIR_DOWN) //If Link is facing down...
            {
            lw->Flip = 2; //Change direction of spriteUsed to down.
            }
        if(Link->Dir == DIR_RIGHT) //If Link is facing right.
            {
            lw->Tile += 1; //Use next tile as well.
            }
        if(Link->Dir == DIR_LEFT)
            {
            lw->Tile += 1; //If Link is facing left.
            lw->Flip = 1; //Flip spriteUsed tile and use next tile as well.
            }
		
        }
        
		else{
    Game->PlaySound(SFX_ERROR); //If out of MP, play ERROR SOund Effects.
    }
    }
}

/////////////////////////////
/// Lightning Bolt Spell //////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////
/// D0: Damage of lightning projectile.                                 ///
/// D1: Sprite used or lightning prpjectile; select graphics from:      ///
///            Quest->Graphics->Sprites->WeaponsMisc.                   ///   
/// D2: MP cost per use of item.                                        ///
/// D3: Speed of projectile (suggest 200).                              ///
/// D4: FFC Script Slot for 'FlashScren' FFC Script.                    ///
/// D5: Colour of flash. Select colour (decimal) from:                  ///
///      Quest->Graphics->Palettes->Main (Suggest 1)                    ///
/// D6: Duration to flash scfeen (in frames; suggest 45)                /// 
/// D7: Amount of damage to non-targeted enemies on screen.             /// 
/////////////////////////////////////////////////////////////////////////// 


item script BoltSpell{
    void run(int power, int boltSprite, int magicCost, int speed, int Script_ID, int Color, int Duration, int screenDamage){
	 if (Game->Counter[CR_MAGIC] > magicCost) //Fill in the numbers for magic consumption and number of projectiles allowed on screen
        {
	 Screen->Wavy = 10;
	 Game->Counter[CR_MAGIC] -= magicCost;
	 int args[8] = {Color, Duration};
 npc enemys;
   for(int i = 1; i<=Screen->NumNPCs(); i++)
         {
         enemys = Screen->LoadNPC(i);
         enemys->HP-=screenDamage;
         }
        
	
		int startX;
        int startY;
        int startHP = Link->HP;
        lweapon bolt;
        Game->PlaySound(ThunderSFX);
        startX = Link->X+8;
        startY = Link->Y+8;
        Link->Action = LA_ATTACKING;
        bolt = NextToLink(LW_ARROW, 8);                        //Create in front of Link
        bolt->UseSprite(boltSprite);                            //Graphics (invisible)
        bolt->Damage = power;                                    //Damage
        bolt->Step = speed;                                    //Speed
		RunFFCScript(Script_ID, args);
		}
		else{
    Game->PlaySound(SFX_ERROR); //If out of MP, play ERROR Sound Effects.
    }
    }
}



/////////////////////////
/// Flash Screen ////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////
/// D0: Colour of flash. Select colour (decimal) from:            ///
///      Quest->Graphics->Palettes->Main (Suggest 1)              ///
/// D2: Duration to flash scfeen (in frames; suggest 45)          ///   
/////////////////////////////////////////////////////////////////////

ffc script FlashScren{
    void run(int colour, int duration){
	
        while(duration > 0){
            if(duration % 2 == 0) Screen->Rectangle(6, 0, 0, 256, 172, colour, 1, 0, 0, 0, true, 64);
            duration--;
            Waitframe();
        }
    }
}




0 user(s) are reading this topic

0 members, 0 guests, 0 anonymous users