Jump to content

Photo

Sword of 100 Pieces

item sword

  • Please log in to reply
17 replies to this topic

#1 Smiles the Death Bringer

Smiles the Death Bringer

    The smiling demon!

  • Members
  • Real Name:William
  • Gender:Male
  • Location:Dream Land

Posted 08 January 2018 - 12:45 PM

I would like a script item. A sword that you pick up piece by piece (With 100 pieces in total). You can still use it with just 1 piece, but every time you pick up 10 pieces, it upgrades. I'd like each subsequent upgrade to up the strength by 1 point. As well as combos that can only be destroyed by each different level of upgrade.

I would also like a counter for the HUD that displays how many sword pieces you have.

 

Thank you

Smiles

 

Edit: I'm going to go ahead and try to learn how to script myself. I'm already pretty fluent in Python and I'm in college for programming anyway. So, I should really take the time to learn this.


Edited by Smiles the Death Bringer, 08 January 2018 - 01:48 PM.

  • Dimentio likes this

#2 Avaro

Avaro

    Quest maker

  • Members
  • Real Name:Robin
  • Gender:Male
  • Location:Germany

Posted 08 January 2018 - 03:58 PM

You should set up 1 item for each sword level (so 10 swords) and then a script that gives you the next sword whenever the counter reaches the next 10. The sword pieces themselves and the counter on the subscreen won't require a script and can be done with the item editor and subscreen editor.

 

The combo that can only be destroyed by each of the different swords will need another script.


  • Smiles the Death Bringer likes this

#3 ZoriaRPG

ZoriaRPG

    The Timelord

  • ZC Developers
  • Gender:Unspecified
  • Location:Prydon Academy

Posted 09 January 2018 - 05:46 AM

I would like a script item. A sword that you pick up piece by piece (With 100 pieces in total). You can still use it with just 1 piece, but every time you pick up 10 pieces, it upgrades. I'd like each subsequent upgrade to up the strength by 1 point. As well as combos that can only be destroyed by each different level of upgrade.
I would also like a counter for the HUD that displays how many sword pieces you have.
 
Thank you
Smiles
 
Edit: I'm going to go ahead and try to learn how to script myself. I'm already pretty fluent in Python and I'm in college for programming anyway. So, I should really take the time to learn this.

(Emphasis, mine.)
 
That is an exceptional attitude towards ZScript! 
 
If you need help learning to use the scripting language, I'm happy to assist.
 
Some things to note:
 
Unlike Python's (IMO, idiotic) tab scope, ZScript uses C/C++ style braces. Tabs are only used for visual cleanliness, so, both of the following are identical.
 

 
You should read ZScript.txt: Use this zscript.txt file, as it is updated with information that is exceptionally useful, including basic syntax and usage information.
 
After reading this, you will want to peruse std_functions.zh, and std_constants.zh, and read their associated docs.
 
 
Insofar as your script request, there is a far better (and more efficient) way to do this, than having ten items:



import "std.zh"

const int CR_SWORDPART = 10; //The 'Script / Custom 4' counter.
const int I_HUNDRED_PIECE_SWORD = 123; //Custom item 1

const int HUNDRED_PIECE_SWORD_BASE_POWER = 1; //The minimum damage of the sword, before it is upgraded.

//A pick-up/collect script. Attach to a sword piece item.
//If you want ZC to display a screen string when the player picks it up, assign the ZQuest String ID
//to the D0 arg.
//If you want a special message when the player collects ten pieces, assign that ZQuest
//string to the D1 arg.
//If you want this to play a special sound if the player picks up ten pieces, assign that Sound Effect
//ID to the D2 arg.
item script swordpart
{
    void run(int msg_id, int special_msg_id, int special_sfx)
    {
        ++Game->Counter[CR_SWORDPART];
        itemdata sword = Game->LoadItemData(I_HUNDRED_PIECE_SWORD);
        sword->Power = Max(( Game->Counter[CR_SWORDPART] / 10 ),HUNDRED_PIECE_SWORD_BASE_POWER);
        
        
        if ( Game->Counter[CR_SWORDPART] % 10 || special_msg_id < 1 )
        {
            Screen->Message(msg_id);
        }
        else
        {
            Screen->Message(special_msg_id);
            if ( Game->Counter[CR_SWORDPART] % 10 == 0 && special_sfx )
            {
                Game->PlaySound(special_sfx);
            }
        }
        
    }
}

//Assign this to global slot 4 ('onContinue')
//This re-applies the power modifications to the sword, every time that the player returns to
//the game, after exiting.
global script OnContinue
{
    void run()
    {
        itemdata sword = Game->LoadItemData(I_HUNDRED_PIECE_SWORD);
        sword->Power = Max(( Game->Counter[CR_SWORDPART] / 10 ), HUNDRED_PIECE_SWORD_BASE_POWER);
    }
}
    

//This is an ffc script to use as a special trigger.
//To use it, place an ffc over the combo that you want to change, assign combo 1 to its
//combo data field (combo 1 should be BLANK: Do not use Combo 0, as ffcs with
//combo 0 cannot run scripts.
//Then, assign this script to the ffc.
//Set the D0 arg to the minimum power that you wish the sword check to use.
ffc script sword_power_trigger
{
    void run(int min_power)
    {
        lweapon l; int q;
        while(true)
        {
            for ( q = Screen->NumLWeapons(); q > 0; --q )
            {
                l = Screen->LoadLWeapon(q);
                if ( l->Damage >= min_power )
                {
                    if ( Collision(l,this) )
                    {
                        //Advance the combo under the ffc by one,
                        ++Screen->ComboD[ComboAt(this->X, this->Y)];
                        //and clear any special flags
                        Screen->ComboF[ComboAt(this->X, this->Y)] = 0;
                        Screen->ComboI[ComboAt(this->X, this->Y)] = 0;
                        Game->PlaySound(SFX_SECRET);
                        Quit();
                    }
                }
            }
            Waitframe();
        }
    }
}
              


I have not tested this, other than ensuring that it compiles, but it should suffice. You need only two items to use this:
A sword: Assign the item ID of the sword item to the constant 'I_HUNDRED_PIECE_SWORD'.
A sword fragment: Assign the item script 'swordpart' to this item .
 
;)
  • ShadowTiger and Smiles the Death Bringer like this

#4 Dimentio

Dimentio

    Beware false Gollabs, who inwardly are Moral Conflicts

  • Members
  • Real Name:Joshua
  • Gender:Male
  • Location:America's Hat.

Posted 09 January 2018 - 07:50 AM

Fixed some problems I found with Zoria's code. Also untested. EDIT: fixed another issue.

#FixingZoria'sJankIn2018


Also, I meant to point this out yesterday or so, but I want to point out how great this script request is. You've specified exactly what you wanted, how you wanted the script to act, and did so in a clear, concise manner. Not only, but the script request itself was realistic and not unreasonable. This is a great example of a good script request, and more people on this forum could learn from your example (this is the main reason I liked your post yesterday).


Edited by Dimentio, 09 January 2018 - 08:30 AM.

  • Anthus and Smiles the Death Bringer like this

#5 Smiles the Death Bringer

Smiles the Death Bringer

    The smiling demon!

  • Members
  • Real Name:William
  • Gender:Male
  • Location:Dream Land

Posted 09 January 2018 - 08:34 AM

Thanks. I'll test it out right away!



#6 Smiles the Death Bringer

Smiles the Death Bringer

    The smiling demon!

  • Members
  • Real Name:William
  • Gender:Male
  • Location:Dream Land

Posted 09 January 2018 - 09:01 AM

Okay, so most of it works, except whenever I use the sword, all the combos on screen go black, even if the sword_power_trigger FFC isn't on screen.

 

Also, is it possible to have different graphics for the different levels of the sword?



#7 Dimentio

Dimentio

    Beware false Gollabs, who inwardly are Moral Conflicts

  • Members
  • Real Name:Joshua
  • Gender:Male
  • Location:America's Hat.

Posted 09 January 2018 - 09:52 AM

Whose script are you using, mine or Zorias? Regardless, that sounds a bit odd, as the sword itself shouldn't have any scripts attached.



#8 Smiles the Death Bringer

Smiles the Death Bringer

    The smiling demon!

  • Members
  • Real Name:William
  • Gender:Male
  • Location:Dream Land

Posted 09 January 2018 - 09:55 AM

Yours.

I didn't put any scripts on the sword. It does it even if there are no sword pieces.


Edited by Smiles the Death Bringer, 09 January 2018 - 09:58 AM.


#9 Dimentio

Dimentio

    Beware false Gollabs, who inwardly are Moral Conflicts

  • Members
  • Real Name:Joshua
  • Gender:Male
  • Location:America's Hat.

Posted 09 January 2018 - 10:51 AM

Does it do it if you swing the sword on a screen without the trigger before swinging it on a screen with the trigger?



#10 Smiles the Death Bringer

Smiles the Death Bringer

    The smiling demon!

  • Members
  • Real Name:William
  • Gender:Male
  • Location:Dream Land

Posted 09 January 2018 - 10:57 AM

Yeah.



#11 Smiles the Death Bringer

Smiles the Death Bringer

    The smiling demon!

  • Members
  • Real Name:William
  • Gender:Male
  • Location:Dream Land

Posted 09 January 2018 - 01:56 PM

I figured out the problem. If D1 is set to 0, then everything that has no flag, becomes a sword 1 flag.

Dunno why it makes every screen do that. When you set D1 to anything else, it's only active on that screen.


Edited by Smiles the Death Bringer, 09 January 2018 - 01:58 PM.


#12 Smiles the Death Bringer

Smiles the Death Bringer

    The smiling demon!

  • Members
  • Real Name:William
  • Gender:Male
  • Location:Dream Land

Posted 09 January 2018 - 02:20 PM

I also managed to modify the code where you get a different sword every level (You don't see any problems with it do you?):

 
import "std.zh"
const int CR_SWORDPART = 10; //The 'Script / Custom 4' counter.
int I_HUNDRED_PIECE_SWORD = 123; //Custom item 1


const int HUNDRED_PIECE_SWORD_BASE_POWER = 1; //The minimum damage of the sword, before it is upgraded.


//A pick-up/collect script. Attach to a sword piece item.
//If you want ZC to display a screen string when the player picks it up, assign the ZQuest String ID
//to the D0 arg.
//If you want a special message when the player collects ten pieces, assign that ZQuest
//string to the D1 arg.
//If you want this to play a special sound if the player picks up ten pieces, assign that Sound Effect
//ID to the D2 arg.
//!Dimentio Edit: Fixed decimal values being passed to sword->Power,
//!Fixed bug where having 10-19 sword pieces is the same as having 0-9.
item script swordpart
{
    void run(int msg_id, int special_msg_id, int special_sfx)
    {
        ++Game->Counter[CR_SWORDPART];
        itemdata sword = Game->LoadItemData(I_HUNDRED_PIECE_SWORD);
        sword->Power = Max((Floor(Game->Counter[CR_SWORDPART] / 10) + 1), HUNDRED_PIECE_SWORD_BASE_POWER);
        
        
        if ( Game->Counter[CR_SWORDPART] % 10 || special_msg_id < 1 )
        {
            Screen->Message(msg_id);
        }
        else
        {
            Screen->Message(special_msg_id);
            if ( Game->Counter[CR_SWORDPART] % 10 == 0 && special_sfx )
            {
                Game->PlaySound(special_sfx);
                I_HUNDRED_PIECE_SWORD += 1;
                Link->Item[I_HUNDRED_PIECE_SWORD] = true;
            }
        }
        
    }
}


//Assign this to global slot 4 ('onContinue')
//This re-applies the power modifications to the sword, every time that the player returns to
//the game, after exiting.
//!Dimentio Edit: Fixed decimal values being passed to sword->Power,
//!Fixed bug where having 10-19 sword pieces is the same as having 0-9.
global script OnContinue
{
    void run()
    {
        itemdata sword = Game->LoadItemData(I_HUNDRED_PIECE_SWORD);
        sword->Power = Max((Floor(Game->Counter[CR_SWORDPART] / 10) + 1), HUNDRED_PIECE_SWORD_BASE_POWER);
    }
}
    
//!Dimentio Edit: This entire ffc script + comments. Sorry Zoria, I don't think your method was the most efficient.
//D0: Number of pieces you need to own to trigger
//D1: Flag to trigger
//The way this works is that it changes all combos with flag D1 to the wooden sword trigger flag.
//Leaving things to the engine is generally a safe way to do thing.
//This also means you only need one script of this running.
ffc script sword_power_triggers
{
    void run(int power, int flag)
    {
        while(true)
        {
    if (Game->Counter[CR_SWORDPART] >= power)
    {
for (int i = 0; i < 176; i++)
                {
                    if (Screen->ComboF[i] == flag)
                    {
                        Screen->ComboF[i] = CF_SWORD1;
                    }
                    if (Screen->ComboI[i] == flag)
                    {
                        Screen->ComboI[i] = CF_SWORD1;
                    }
                }
            }
            Waitframe();
        }
    }
}   

Edited by Smiles the Death Bringer, 09 January 2018 - 02:21 PM.


#13 ZoriaRPG

ZoriaRPG

    The Timelord

  • ZC Developers
  • Gender:Unspecified
  • Location:Prydon Academy

Posted 09 January 2018 - 09:24 PM

 

I also managed to modify the code where you get a different sword every level (You don't see any problems with it do you?):

[...]

 

 

That looks fine, although it means wasting items; which is mandatory in 2.50.x...

 

One thing that I would mention, is that you should not get into the habit of doing this:

I_HUNDRED_PIECE_SWORD += 1

...unless you need to increment more than 1.

 

In general, you want ++variable, unless that would damage your code logic. (See: Pre-Increment and Post-increment).

 

Pre-increment is faster in ZScript by 33%, so, you want to be in the habit of using it.

 

 

In 2.54, you would need only do this to accomplish the change in tile/sprites.

        itemdata sword = Game->LoadItemData(I_HUNDRED_PIECE_SWORD);
        sword->Power = Max((Floor(Game->Counter[CR_SWORDPART] / 10) + 1), HUNDRED_PIECE_SWORD_BASE_POWER);
        sword->Sprites[0] = new_stab_sprite;
        sword->Sprites[1] = new_slash_sprite;
        sword->Tile = new_tile;

....and you would use a single item for the entire thing. Much tidier, but, that's still in alpha.

 

 

Whose script are you using, mine or Zorias? Regardless, that sounds a bit odd, as the sword itself shouldn't have any scripts attached.

 

 

Dimentio broke the universe. Yay!

 

 

You might want this:

if ( flag > 0 ) //don't run this this if the flag is set wrong -Z
{
    for (int i = 0; i < 176; ++i) //use ++n in for loops for a 33% speed boost when incrementing the variable.
    {
        if (Screen->ComboF[i] == flag)
        {
                        Screen->ComboF[i] = CF_SWORD1;
            //can't break here, because this is doing it without checking collision, which is fine.
        }
        if (Screen->ComboI[i] == flag)
        {
                        Screen->ComboI[i] = CF_SWORD1;
        }
    }
}

//I have no idea why a flag of 0 would set ComboD[] here. :/ -Z

Please send a copy of the quest where the combos were being set to blank data, to me, so that I can check for ZC bugs. That certainly sounds like a problem that I will need to fix. You can send it by PM, or on Discord/Skype. (My username is the same for all three.)

 

Instead of the if statement to check if the flag is a legal value, I would make a default flag value:

const int HUNDRED_PIECE_SWORD_FLAG = 102; //Script 5

Then, in the ffc script, add a small sanity check:

ffc script sword_power_triggers
{
    void run(int power, int flag)
    {
        if ( flag < 1 ) flag = HUNDRED_PIECE_SWORD_FLAG;

That is a much cleaner way to do this, and it makes it easier to set up the ffcs over time.

 

It also eliminates the need for an if ( flag > 0 ) check, and you do not want that check if you do a sanity check on the flag value first, which means that the script will run faster, and be more reliable:

 

Redundant statements will slow it down. The single check need only run one time, versus a statement that is running every frame.


  • Smiles the Death Bringer and Dimentio like this

#14 Dimentio

Dimentio

    Beware false Gollabs, who inwardly are Moral Conflicts

  • Members
  • Real Name:Joshua
  • Gender:Male
  • Location:America's Hat.

Posted 10 January 2018 - 05:26 AM

I figured out the problem. If D1 is set to 0, then everything that has no flag, becomes a sword 1 flag.

Dunno why it makes every screen do that. When you set D1 to anything else, it's only active on that screen.

WHELP, I forgot to sanity check it. Whoops.

The reason why, if I were to guess, is because setting a combo's inherent flag changes the combo data itself, meaning that it changes every instance of that combo across the quest to use the set flag, until you exit the game. Which is fine for what you're doing, but can cause some problems when you forget to sanity check like an idiot (heheh...).



#15 Smiles the Death Bringer

Smiles the Death Bringer

    The smiling demon!

  • Members
  • Real Name:William
  • Gender:Male
  • Location:Dream Land

Posted 11 January 2018 - 08:12 AM

Please send a copy of the quest where the combos were being set to blank data, to me, so that I can check for ZC bugs. That certainly sounds like a problem that I will need to fix. You can send it by PM, or on Discord/Skype. (My username is the same for all three.)

I sent you a contact request on Skype (You have to be in contacts for me to send files), because I don't have any accounts on file hosting websites, and I can't find you on discord without a number.





Also tagged with one or more of these keywords: item, sword

0 user(s) are reading this topic

0 members, 0 guests, 0 anonymous users