PDA

View Full Version : Majora/SUCCESSOR/CJC Script Collaboration Thread



CJC
09-27-2012, 11:08 PM
Majora
SUCCESSOR
and of course
CJC


There, now that the tags are out of the way.

Majora is trying to get his shield script to work without the muck of Link Tile Modifiers. I've begun to brainstorm a script for this, but I've hit a wall with all the possible actions Link can take while holding a shield.



int WoodenShield = # //Replace with the item number for your wooden shield
int WoodShieldRaised = ### //Replace with the tile number that corresponds to the wooden shield
//When Link is blocking with it.
//Make sure you arrange the tiles in the following order:
//Face Up, Face Down, Face Left, Face Right. Keep the two frame-animations together
int WoodShieldRest = ### //Replace with the tile number that corresponds to the wooden shield
//When Link has it at his side.
//Use the same arrangement as Raised.

If(Link->Item[WoodenShield]){ //Checks if Link has the Wooden Shield
If(Link->InputEx1){ //Button Assigned to the Shield
//Insert the block code for your script here
FastTile(0, Link->X, Link->Y, WoodShieldRaised + Link->Dir*2, WoodShieldCset, 128) //Draws the shield on
//Link's Layer. It should automatically adjust for direction.
}
Elseif(Link->Action == 0){ //Standing Still
FastTile(0, Link->X, Link->Y, WoodShieldRest + Link->Dir*2, WoodShieldCset, 128) //Draws the shield on
//Link's Layer. It should automatically adjust for direction.
Elseif(Link->Action == 1){ //Walking
FastTile(0, Link->X, Link->Y, WoodShieldRest + Link->Dir*2 + 1, WoodShieldCset, 128) //
}
}//And so on in that manner. You've got your work cut out for you on this.
//Also, we'll have to figure out how to handle moving while the shield is raised.
//Perhaps Action == 0 and Action == 1 need to be the uppermost IF statements.


If either of you can work out how to make this script better/more functional/less bloated, give me a tag. I'm stumped.

EDIT: Copy the code into a notepad so you can actually read it.

Gleeok
09-28-2012, 12:31 AM
Depends on how you want blocking to work.

There's Link->Invisible, combined with DrawTile could replace LTMs. Never tried it though.
LA_ATTACKING, *CASTING, *SWIMMING would be the major things to check for.

I'm not sure how you are trying to redo the shield, but a simple


if(Input)
{
Link-Item[shield_id] = true;
shield++;
}
else if(shield > 0)
{
Link-Item[shield_id] = false;
shield = 0;
}

would be built-in behavior + require a button press to block shield effect.

SUCCESSOR
09-28-2012, 10:18 AM
Majora wants a script that doesn't use LTMs for Active shield(when the button is pressed) or doesn't use LTMs at all, CJC ? I altered... well rewrote the script he uses for shields to ghost link(make him invisible and draw over him) when he uses the shields instead of LTMs. This simplifies using LTMs to only being needed for the shield when not in use. I could draw a shield tile over link when he walks(has a shield and not using it) but it would be stuck in one place as I can't think of a way to match it with links walking sprites, it would disappear when you use the sword and such, and would have to be adusted for each shield and whatever tiles are used. Best to stick with LTMs for that IMHO.


const int I_FAKESHIELD1 = 140; //Extra Items 18, 19, and 20
const int I_FAKESHIELD2 = 141; // -change if these items are
const int I_FAKESHIELD3 = 142; // -already in use
const int BUT_SHIELD = 0; // -1 = L, 0 = R, 1 = Ex1, 2 = Ex2, 3 = Ex3, 4 = Ex4 <-Button to use for shield
const int DO_STRAFE = 1; //Any value other than 0 turns on strafing
const int SFX_SHIELDUP = 89; // The sound to use when Shield is held up.
const int TILE_LINK = 34500; //first tile(Small shield facing up)

int walking; //keeps track of link walking
bool lr; //used for L and R
global script ExShield
{
void run()
{
int strafeDir; //stores Link's direction
bool shield; //keeps track on when shield is up


while(true)
{
if(BUT_SHIELD == -1 && Link->InputL){Link->InputL = false; lr = true;}
else if(BUT_SHIELD == 0 && Link->InputR){Link->InputR = false; lr = true;}
else lr = false;
if(!shield)strafeDir = Link->Dir;
if(ShieldInput() && !shield && !DoingMore()) //Shield button pressed and shield is inactive.
{
shield = true;
Link->Invisible = true;
if(Link->Item[I_FAKESHIELD3]) Link->Item[I_SHIELD3]=true;
else if(Link->Item[I_FAKESHIELD2]) Link->Item[I_SHIELD2]=true;
else if(Link->Item[I_FAKESHIELD1]) Link->Item[I_SHIELD1]=true;
else shield = false;
if(shield) Game->PlaySound(SFX_SHIELDUP);
}
else if((!ShieldInput() && shield) || (DoingMore() && shield))
{
shield = false;
Link->Invisible = false;
Link->Item[I_SHIELD3] = false;
Link->Item[I_SHIELD2] = false;
Link->Item[I_SHIELD1] = false;
}
if(shield && ShieldInput())
{
if(DO_STRAFE){
Waitdraw();
GhostLink(strafeDir);
Link->Dir = strafeDir; } //forces link to face the same direction
else GhostLink(); //draws link
}

Waitframe();
} //end of while loop
}// end of run
bool ShieldInput()
{
if(BUT_SHIELD == 1 && Link->InputEx1) return true;
else if(BUT_SHIELD == 2 && Link->InputEx2) return true;
else if(BUT_SHIELD == 3 && Link->InputEx3) return true;
else if(BUT_SHIELD == 4 && Link->InputEx4) return true;
else return lr;
}
bool DoingMore() //checks for any action besides walking
{
for(int i = 2; i < 25; i++)
{
if(Link->Action == i) return true;
}
return false; //if function reaches the end of for loop returns false
}
void GhostLink() //Draws Link. Three tiles for each direction in order: Up Down Left Right
{
int val = TILE_LINK; //set initial tile

if(Link->Item[I_FAKESHIELD3]) val += 40; //move to row for Shield current shield
else if(Link->Item[I_FAKESHIELD2]) val += 20;

if(Link->Dir == DIR_RIGHT) val += 9; //move to first tile for direction
else if(Link->Dir == DIR_LEFT) val += 6;
else if(Link->Dir == DIR_DOWN) val += 3;

if(Link->Action == LA_WALKING)walking++; //alternate for walking
if(walking >= 64)walking = 0;
else if(walking >= 48)val += 2;
else if(walking >= 16 && walking <= 32) val += 1;

Screen->FastTile(2, Link->X, Link->Y, val, 6, 128); //draw tile.
}
void GhostLink(int dir) //Draws Link in one direction.
{
int val = TILE_LINK; //set initial tile

if(Link->Item[I_FAKESHIELD3]) val += 40; //move to row for Shield current shield
else if(Link->Item[I_FAKESHIELD2]) val += 20;

if(dir == DIR_RIGHT) val += 9; //move to first tile for direction
else if(dir == DIR_LEFT) val += 6;
else if(dir == DIR_DOWN) val += 3;

if(Link->Action == LA_WALKING)walking++; //alternate for walking
if(walking >= 64)walking = 0;
else if(walking >= 48)val += 2;
else if(walking >= 16 && walking <= 32) val += 1;

Screen->FastTile(2, Link->X, Link->Y, val, 6, 128); //draw tile.
}
} //end of global script

For anyone that doesn't know how to use this script: You make three custom items, "Dummy Shields," and give those in the quest as you would the real shields. The dummies are the items that show up in the inventory and can be used for LTMs for when the shield isn't in use. Other than that all you need to do is set the constants to your liking.

Example quest. (https://dl.dropbox.com/u/94061979/ExShield.qst)

How the tiles it uses are laid out.
https://dl.dropbox.com/u/94061979/ExShieldLink.png

CJC
10-28-2012, 09:06 PM
Majora

Okay, now we're going to work on getting these potion shops to work.

EDIT: This script will not work as intended. Sorry.

-=SPOILER=-

SUCCESSOR
11-02-2012, 02:08 AM
I'm sorry CJC and Majora I know I promised to make some functions to get the ball rolling on this idea but I have been lazy and haven't scripted a damn thing in like a week. Just to remind myself:

The shop is 3 cauldrons, each selling one type of potion(one ffc used 3 times). There are 4 empty bottle items each it's own class. Each bottle class has 7 items(potentially 8 if there are fairy in a bottle): Empty, IngredRED, IngredGREEN, IngredBLUE, Red, Green, Blue. The shop first checks if you have the ingredient for it's potion and if you do gives you a discounted price. If you do not then the shop check for an empty bottle and charges full price or show the No Empty Bottle string. Shop also needs a string for not enough money. Did I forget anything?

Majora
11-03-2012, 05:40 PM
So should I begin rearranging items to be sequential? or will be it constants-based? Before I commit the change to my quest file.


EDIT: If it will facilitate the item check process, the "Keep lower level items" can be un-checked and the potions script I have can give link the relevant bottle item once the potion/ingredient is consumed. The potion script I have is basically multiple minorly-edited variant of:


//D0 is item to give
item script EnadylPotion{
void run(int asdf, int itm){ // "int asdf" is skip over the D0 variable which is used by the item-pickup-message script
Link->HP = Link->MaxHP;
//Link->Item[itm] = true;
}
}

SUCCESSOR
11-04-2012, 07:15 AM
That wont be necessary. I have the function that checks for an empty bottle working. For some reason the function that checks for a relevent ingredient item is screwing things up. Teach me to script at 5am... or 4am damn DST. I meant to only do a couple functions but the shop script was easy to edit and I like to test what I script. I will post what I have when I get home whether or not I figure out wth I am doing wrong.

EDIT: Figured out my dumb ass mistake. Here's the code. Remember I wrote this at 5 am so it will have bugs and will need polish.

-=SPOILER=-

You do realize that item script is all kinds of jacked right? EDIT: If you want I can write you some item scripts.

Majora
11-04-2012, 01:41 PM
There are some issues with compiling. it's mostly conflicts so far. Can I use the original shop script with the cauldron one? Because for example, I got a "Function Shopcanbuy was already declared with that type signature" error.

EDIT: it also conflicts with this script but I commented out some parts and will see if it works:
EDIT 2: The item scripts for the potions and ingredients are hilariously simple, yeah. they're instant-use potions. I was going to eventually see about scripting the "everything freezes while your health gradually refills" effect that the built-in potions have.

ffc script Chest{ // Allow Link to open the treasure chest at this FFC's location using the
// set input.
// D0 = input: set to 0 for A button, 1 for B button, 2 for L, 3 for R.
void run(int input){
int loc = ComboAt(this->X,this->Y);
while(!AgainstComboBase(loc) || !SelectPressInput(input)) {
// Uncomment to prevent Link from opening the chest normally:
if (AgainstComboBase(loc)) {
Link->InputUp = false;
}
Waitframe();
}
for (int i = 0; i < 8; i++) { // 8 pixels/frame gives 1/2 of a combo.
// Similate pressing up for 5 frames, and mark this chest as
// opened if the combo at this ffc is still a chest type.
SetInput(input, false);
Link->InputUp = true;
Waitframe();
}
}
bool AgainstComboBase(int loc){
return Link->Z == 0 && (Link->Dir == DIR_UP && Link->Y == ComboY(loc)+8 && Abs(Link->X-ComboX(loc)) < 8);
}
}


//Only include these two functions once in your script file
//bool SelectPressInput(int input){
// if(input == 0) return Link->PressA;
// else if(input == 1) return Link->PressB;
// else if(input == 2) return Link->PressL;
// else if(input == 3) return Link->PressR;
// else if(input == 4) return Link->PressEx2;
//}
//
//void SetInput(int input, bool state){
// if(input == 0) Link->InputA = state;
// else if(input == 1) Link->InputB = state;
// else if(input == 2) Link->InputL = state;
//else if(input == 3) Link->InputR = state;
//else if(input == 4) Link->InputEx2 = state;
//}

EDIT3: The string for "You don't have a bottle" keeps popping up even though I do have the bottle items and the constants have been set. :/ I'll keep poking around though to see if maybe something was set up wrong by me somewhere.

SUCCESSOR
11-04-2012, 05:06 PM
If there are duplicate function just take one out. My SelectPressInpute() and SetInput() should be able to be used other scripts without there being a problem(LTM's newest shop -1 would be Ex1 instead or A, B, L, or R). ShopCanBuy() should be unchanged from LTM's script. Let me know what other conflicts there may be. I'll test it out more. I only tested out one bottle last night.

Majora
11-06-2012, 12:01 PM
I just tried this morning and it broke for no reason. This showed up in Allegro.log after wondering why the cauldrons refused to sell me potions.

Invalid index (25) to local array of size 4
Invalid index (25) to local array of size 4
Invalid index (17) to local array of size 4
Invalid index (17) to local array of size 4
Invalid index (9) to local array of size 4
Invalid index (9) to local array of size 4
Invalid index (31) to local array of size 4
Invalid index (30) to local array of size 4
Invalid index (29) to local array of size 4
Invalid index (28) to local array of size 4
Invalid index (27) to local array of size 4
Invalid index (26) to local array of size 4
Invalid index (25) to local array of size 4
Invalid index (24) to local array of size 4
Invalid index (23) to local array of size 4
Invalid index (22) to local array of size 4
Invalid index (21) to local array of size 4
Invalid index (20) to local array of size 4
Invalid index (19) to local array of size 4
Invalid index (18) to local array of size 4
Invalid index (17) to local array of size 4
Invalid index (16) to local array of size 4
Invalid index (15) to local array of size 4
Invalid index (14) to local array of size 4
Invalid index (13) to local array of size 4
Invalid index (12) to local array of size 4
Invalid index (11) to local array of size 4
Invalid index (10) to local array of size 4
Invalid index (9) to local array of size 4
Invalid index (8) to local array of size 4
Invalid index (7) to local array of size 4
Invalid index (6) to local array of size 4
Invalid index (5) to local array of size 4
Invalid index (4) to local array of size 4

SUCCESSOR
11-06-2012, 02:44 PM
Seems to be failing to read bottles[].

You just opened the quest again or did you change something?

Majora
11-06-2012, 03:13 PM
I just opened the quest in ZQ after seeing in ZC that I couldn't buy any potions.

EDIT: how would I go about throwing in a trace function or w/e for debugging?

SUCCESSOR
11-06-2012, 04:24 PM
What I meant is did you change anything since before you last tested it and it worked?

Majora
11-06-2012, 04:38 PM
pretty sure I haven't. I am going to re-import the script you have in this thread to see if that works. even if it means I get 8 bombs again so long as it just lets me buy potions. XD

I even downloaded a program that compares text files to check for discrepancies :I



EDIT: After reverting to your version (the one in this thread), and starting a new file, I can once again buy potions normally and it all works correctly. ZC, what the fuck.

SUCCESSOR
11-08-2012, 10:25 PM
like I said I tested it in RC4 and RC5 and it worked perfectly. There must have been some other factor. Did you ever get around to testing all 4 bottles? That is still the plan for your quest right?

And this script(and pretty much everything I do) is free for anyone to use. Just post any questions you have here. Let me know what you think.

Majora
11-14-2012, 03:21 AM
So, right! Plant FFC:

It basically does everything the cauldron does EXCEPT the only variables will be the following, as well as the FFC becoming inactive (and switch to another tile/combo) while the respawn timer counts down (which doesn't start to count down until link leaves the screen, if possible.) and of course, doesn't charge rupees/money:

D0: Category (red/green/blue)
D1: string for not enough room in inventory
D2: respawn time in frames (frames/tics the only unit of measurement that ZC knows exists besides pixels)
D3: tile/combo to switch to for inactive (which will of course be sequential for not needing a d variable for the "active" tile/combo?)
D4: string to play when link "talks" to the ffc (i.e. "you check the plant...")

That should be it I think. Optional stuff could be:

D5: A 1 in (this variable) chance to be harvested an extra time.
D6: A 1 in (this variable) chance to restore 50% of Link's HP/MP (or both if blue) when harvesting.







That should cover it I hope.