I tried the script combiner again and i got this.
//Paste your current global script in here
//Paste the global script you want to add in here
// import "std.zh" // Only need this once.
// Passive Subscreen A/B Counter Fix
// A fix to display the proper counter for the A and B buttons on the passive subscreen when the quest rule "Can Select A-Button Weapon on Subscreen" is on.
//
// In your Slot2 (or Active) global script, put SetCountersAB(); before the waitframe.
// A sample global script is commented out at the bottom.
//
// See notes below about the constants used ESPECIALLY if your quest makes use of the Script1-25 item counters. If you're not sure, you'll likely be safe with the defaults.
//
// On your passive subscreen, place a Counter object with each Button Item display. Edit the properties.
// On the Attributes Tab, change Item 1 to the corresponding Script counter - default is A Button = Script 24, B Button = Script 25
// Leave "Show Zero" and "Only Selected" UNCHECKED.
//
// Note: make sure that your item has its Counter Reference declared. Edit the item, Pickup tab.
// For instance, Arrows are hardcoded to use either rupees or arrows. Unless the Counter Reference is set, the counter won't show.
// This should point to the item's counter NOT the script counters used by this script.
//
// Set these constants to unused Script counters. Valid numbers would be 7-31.
// By default they are set to the highest values to hopefully avoid interfering with any other scripts.
// The counter values and associated references are all in std_constants.zh
// You'll need to know the counter reference number NOT the value. So for the defaults, you'll need to use Script Counters 24 & 25.
const int CR_ABUTTON = 30; // Script 24 counter reference
const int CR_BBUTTON = 31; // Script 25 counter reference
void SetCountersAB(){
itemdata itemA = Game->LoadItemData(GetEquipmentA());
itemdata itemB = Game->LoadItemData(GetEquipmentB());
if(GetEquipmentA()==0){
Game->Counter[CR_ABUTTON]=0;
}else if(Game->Counter[CR_ABUTTON]!=Game->Counter[itemA->Counter]){
Game->Counter[CR_ABUTTON]=Game->Counter[itemA->Counter];
}
if(GetEquipmentB()==0){
Game->Counter[CR_BBUTTON]=0;
}else if(Game->Counter[CR_BBUTTON]!=Game->Counter[itemB->Counter]){
Game->Counter[CR_BBUTTON]=Game->Counter[itemB->Counter];
}
}
// global script active{
// void run(){
// while(true){
// Might have other stuff here...
//
// SetCountersAB();
//
// Waitframe();
// }
// }
//}
// -------------------------------------------
// --- Consumable Game-Boy Styled Shields ---
// --- with advanced defense options ---
// --- by justin, request gouanaco ---
// --- based on Simplified GBShield Script ---
// --- by MoscowModder and others ---
// --- ver 1.0 ---
// -------------------------------------------
//
// Setup instructions
// 1. Check/set the constants below the instructions (sound SFXs, durability display, and eweapon->Misc[] index)
// 2. Combine global script with your existing slot2/active global, or if no existing global active, just use the example version
// 3. Compile/Import the script into your quest
// 3.1 set the global to its slot
// 3.2 set the item script gbshield to a slot
//
// 4. For every equipable/consumable/advanced shield you will need two items. Let's call them Item1 and Item2 for clarity with their particular setups.
// Item1
// The actual shield. Itemclass shield. Give this one a Link Tile Modifier to your tiles of Link carrying this shield.
// This shield can still use normal shield block/reflect flags (see below) on the first page of the editor giving this script even more customization.
// This shield can also take advantage of the consumable/advanced defense options by using the D values on the Scripts tab (you don't actually attach a script)
// See, Item1 Options at end of these instructions for the standard block/reflect flags and all the D value options.
//
// Item2
// The "dummy" shield item. Itemclass custom. This is the item that will be usable on your A/B buttons. When used it gives the actual shield (Item1).
// On the script tab, attach the gbshield script to the Action slot. Set the D values.
// DO: "Real" shield item# to give
// D1: Dummy shield item#, the item# that this script is attached to
// D2: Durabilty save slot. If multiple consumable shields exist in the quest use this to save the current durabilty of each one.
// Give each individual shield a unique value between 0 and 4.
// the script is hardwired to only save 5 durability values. expansion is possible by increasing the size of the CGBShieldVars[] array.
// to increase the array size, see note at bottom of this script file.
//
// 5. That's it.
// ---------------------------
//
// Item1 Options
//
// Standard block/reflect flags - sum the numbers. eg: shield blocks - rock, arrow, fireball, script = 1+2+8+128 = 139
// 1 - rock
// 2 - arrow
// 4 - boomerang
// 8 - fireball
// 16 - sword beam
// 32 - magic
// 64 - fire
// 128 - script weapons
// 256 - boss fireball
//
// Advanced consumption and defense options for the Script Tab of Item1
// D0 = the shield's durability (HP)
// D1-D7 are for the highly customizable consumption/defense options. you don't need to set them all. this is their format.
// xxxxxxx.yy
// a positive x value means we want to use the standard block/reflect flags as above. (can be different than block/reflect on Data page)
// a negative x value means we want to use the advanced block/reflect flags below. ( NOT to be combined like standard block/reflect flags)
// the y value sets how the shield/Link handles the weapon(s) defined by x.
//
// Negative X values ( NOT to be combined like standard block/reflect flags)
// rock = 1 arrow = 2 boomerang = 3 fireball = 4 swordbeam = 5 magic = 6
// fire = 7 gen.script = 8 fireball2 = 9 proj.bomb = 10 bombblast = 11 proj.supbomb = 12
// supbombblast = 13 firetrail = 14 wind = 15 fire2 = 16 script1 = 17 script2 = 18
// script3 = 19 script4 = 20 script5 = 21 script6 = 22 script7 = 23 script8 = 24
// script9 = 25 script10 = 26
//
// Y Values (divided up between tens column and ones column)
// Tens column
// .0y == shield takes no damage
// .1y == shield takes all the eweapon damage
// .2y == shield takes half the eweapon damage
// .3y == shield takes half the eweapon damage, and diminshes the strength of the eweapon by that amount
// .4y == shield takes quarter the eweapon damage
// .5y == shield takes quarter the eweapon damage, and diminshes the strength of the eweapon by that amount
// .6y == shield takes double the eweapon damage
// .7y == shield takes triple the eweapon damage
// .8y == eweapon one-hit-kills shield
// Ones column
// .y0 == Regardless of above, Link will not be hurt (eweapon was destroyed by shield)
// .y1 == If shield breaks, Link takes the extra damage left over. eg Shield durability = 10, weapon damage = 15, Link will lose 5HP and shield gone
// .y2 == Reflect eweapon, Link will not be hurt. But shield may have been damaged in process
// .y3 == Despite shield, Link gets full weapon damage
// .y4 == Despite shield, Link gets half weapon damage
// .y5 == Despite shield, Link gets quarter weapon damage
// .y6 == Despite shield, Link gets double weapon damage
// .y7 == Despite shield, Link gets triple weapon damage
// the .y3 thru .y7 values allow for significant customization, for instance a 14 value gives a shield that takes full damage, but still gives Link half damage
// obviously some of the variations would be very mean if implimented, but who am I to decide...
//
// Example usage:
// D0 = 100 shield has 100 hp durability
// D1 = 38.21 shield will take half damage (.2y) from magic, boomr, arrow (32+4+2=38). If shield breaks (.y1) Link takes leftover damage from these weapons.
// D2 = -11.84 shield will be destroyed (.8y) by a bombblast (-11), but Link will only take half damage from the blast (.y4)
// D3 = 24.32 shield will take half damage (.3y) from fireball, swordbeam (8+16=24), and half dimished weapon will be reflected (.y2)
Is this right?
and this
int CGBShieldVars[37]; // a global array that stores all the variables used by this script. see the bottom of this script file for the index values.
// --------------------------------------
// constants you may wish/need to change
const int CGBS_DURADISPLAY = 1; // 0 = no display, 1 = set to counter, can be placed on subscreen
const int CGBS_DURACOUNTER = 7; // default 7 = CR_SCRIPT1 counter, change depending on the counter usage in your quest.
const int SFX_GBSHIELD = 17; //Shield active SFX (note: this is the Hookshot sound in the default Z1 tileset)
const int SFX_SHIELDBREAK = 0; // SFX to use when shield breaks, the default value of 0 means that none is set
// this script also uses the following sound effects which the quest designer may wish to change (do a search)
// SFX_CLINK, the standard shield collision sound
// SFX_OUCH, the standard Link hurt sound
const int EW_MISC_CGBS = 0; // an index to the eweapon->Misc[] array. if any other scripts use this array you might have to change this value.
// ----- end constants -----------------
// --------------------------------------
// Example global active script, if combining with an existing global active script add, before the Waitframe(); the following two lines without the // comment tags
// GB_Shield();
// if(CGBShieldVars[CGBS_shieldOn]==1) Consume_Shield();
global script active{
void run(){
while(true){
// the following two lines run the button equipable Game-Boy styled shield, and the Consumable shield with advanced defense options
GB_Shield();
if(CGBShieldVars[CGBS_shieldOn]==1) Consume_Shield();
Waitdraw(); //sometimes doesn't exist in a global active script, if it does, the shield code goes above it.
Waitframe(); //Needed at bottom of while(true) loop
}//end while
}//end void run
}
// ------ end global -------------------
// ------- Item Script -----------------
// Item use script that checks use of dummy shield item and gives an actual shield item
// modified version of gbshield script by MoscowModder (who in turn credits others)
// Attach the script gbshield to the Action slot of the dummy shield item, and set the following arguments (D values)
//DO: "Real" shield item# to give
//D1: Dummy shield item#, the item# that this script is attached to
//D2: Durabilty save slot. If multiple consumable shields exist in the quest use this to save the current durabilty of each one.
// Give each individual shield a unique value between 0 and 4.
// the script is hardwired to only save 5 durability values. expansion is possible by increasing the size of the CGBShieldVars[] array.
// to increase the array size, see note at bottom of this script file.
item script gbshield{
void run ( int shieldID, int dummyID, int duraSaveSlot ){
if(CGBShieldVars[CGBS_curShieldItem] != shieldID) // this dummy shield is connected to different real shield than we've already been using
{
itemdata dummy = Game->LoadItemData( CGBShieldVars[CGBS_dummyShield] ); // get the previous dummy shield
CGBShieldVars[CGBS_DurSlot1 + dummy->InitD[3]] = CGBShieldVars[CGBS_curDur]; // save previous shield durability to its durability slot (connected to its dummy)
for(int i=0;i<CGBS_DurSlot1;i++) CGBShieldVars[i]=0; // clear everything up to the saved durability slots
CGBShieldVars[CGBS_curDur] = CGBShieldVars[CGBS_DurSlot1 + duraSaveSlot]; // get saved durability for this shield
CGBShieldVars[CGBS_curShieldItem] = shieldID; // set the new real shield item#
CGBShieldVars[CGBS_dummyShield] = dummyID; // save this dummy item#
Set_ShieldConsume(shieldID); // get the arguments attached to our real shield and put in our CGBShieldVars[] array
}//endif
if ( Link->PressB ) CGBShieldVars[CGBS_Button] = 1; // shield is on B button
else if ( Link->PressA ) CGBShieldVars[CGBS_Button] = 2; // shield is on A button
CGBShieldVars[CGBS_usedDummy] = 1; // tells our global function to actually give us the real shield
}//end voidrun
}//end itemscript gbshield
// ------ end Item scripts -------------
// ------- Global functions -------------
// Function from gbshield script by MoscowModder (who in turn credits others)
void GB_Shield(){
if( !CGBShieldVars[CGBS_shieldOn] && CGBShieldVars[CGBS_usedDummy]){ //Enable shield when using dummy
CGBShieldVars[CGBS_shieldOn]=1; //Set shield state to on
CGBShieldVars[CGBS_usedDummy]=0;
Link->Item[ CGBShieldVars[CGBS_curShieldItem] ]=true; //Give the shield
Game->PlaySound(SFX_GBSHIELD); //Play the sound
}
else if( ((CGBShieldVars[CGBS_Button] == 2 && !Link->InputA) || (CGBShieldVars[CGBS_Button] == 1 && !Link->InputB)) && CGBShieldVars[CGBS_shieldOn])
{ // button was released, so let's take the shield off.
Link->Item[ CGBShieldVars[CGBS_curShieldItem] ]=false; //Remove shield
CGBShieldVars[CGBS_shieldOn]=0; //Set shield state to off
}
}
// Going to check for valid collisions with our shield, and handle the consumption
void Consume_Shield(){
eweapon ew;
for(int i=Screen->NumEWeapons(); i>0 ; i--) // cycle thru every eweapon on screen
{
ew = Screen->LoadEWeapon(i);
if( !CGBS_EWType(ew->ID) ) continue; // eweapon type isn't something the shield cares about (normal collision, will not affect shield)
ew->CollDetection = false; // turn off engine collisions so we can handle
if( ShieldCollision(ew) ) // check for collision
{
if(ew->Misc[EW_MISC_CGBS] != 666) // hasn't already hit Link/shield
{
Game->PlaySound(SFX_CLINK);
Do_ConsumeShield(ew);
ew->Misc[EW_MISC_CGBS] = 666; // mark this eweapon with the sign of the beast
}//if666
}//ifcollision
ew->CollDetection = true; // turn engine collisions back on in case it's hitting something else
}//forloop ew cycle
if(CGBS_DURADISPLAY == 1) Game->Counter[CGBS_DURACOUNTER] = CGBShieldVars[CGBS_curDur];
}//end Consume_Shield
// a function to check for collision between Link and eweapon, plus correlation between direction Link is facing and location of eweapon.
// it should return true if the eweapon would be hitting Link's shield
bool ShieldCollision(eweapon b)
{
if( ((Link->Z + Link->HitZHeight >= b->Z) && (Link->Z <= b->Z + b->HitZHeight))==false) return false;
int Lx1 = Link->X + Link->HitXOffset;
int Lx2 = Lx1 + Link->HitWidth;
int bx1 = b->X + b->HitXOffset;
int bx2 = bx1 + b->HitWidth;
if( Lx2 < bx1 ) return false;
if( Lx1 > bx2 ) return false;
int Ly1 = Link->Y + Link->HitYOffset;
int Ly2 = Ly1 + Link->HitHeight;
int by1 = b->Y + b->HitYOffset;
int by2 = by1 + b->HitHeight;
if( Ly2 < by1 ) return false;
if( Ly1 > by2 ) return false;
int a = AngleDir8(Angle( Link->X+8, Link->Y+8, CenterX(b), CenterY(b) ));
if(a == Link->Dir) return true;
return false;
}//end ShieldCollision
// we have a collision between the eweapon and our shield, so let's do the consumption junction and some other functions (advanced defense stuff)
void Do_ConsumeShield(eweapon ew)
{
int weapon_type = EWType_to_ConsumeShieldType(ew->ID);
int shieldHurt = Floor(CGBShieldVars[weapon_type] * 0.1);
int linkHurt = CGBShieldVars[weapon_type] - (shieldHurt*10);
int damageShield = 0;
int damageLink = 0;
// get the damage to the shield based on its defense to this threat
if(shieldHurt>0){
if (shieldHurt == 1) damageShield = ew->Damage;
else if(shieldHurt == 2 || shieldHurt == 3) damageShield = ew->Damage * 0.5;
else if(shieldHurt == 4 || shieldHurt == 5) damageShield = ew->Damage * 0.25;
else if(shieldHurt == 6) damageShield = ew->Damage * 2;
else if(shieldHurt == 7) damageShield = ew->Damage * 3;
if(shieldHurt == 3 || shieldHurt == 5) ew->Damage -= damageShield;
}//ifShieldHurt>0
CGBShieldVars[CGBS_curDur] -= damageShield; // damage the shield
// get the damage to Link based on his defense to this threat
if(linkHurt==0){
ew->DeadState = WDS_DEAD; // shield blocked this threat, kill the weapon
}//ifLinkHurt==0
else if(linkHurt==1){ // if shield is negative durability, give the extra damage to Link
if(CGBShieldVars[CGBS_curDur] < 0) damageLink = Abs(CGBShieldVars[CGBS_curDur]);
else ew->DeadState = WDS_DEAD;
if(damageLink > ew->Damage){ // we don't want to hurt Link extra because of double damage to shield
damageLink -= ew->Damage;
if(damageLink > ew->Damage) damageLink -= ew->Damage; // we still don't want to hurt Link extra due to tripled damage to shield
}//ifdamageLink
if(shieldHurt == 3 || shieldHurt == 5) damageLink += ew->Damage;
}//ifLinkHurt==1
else if(linkHurt==2){ // reflect eweapon
lweapon lw = Screen->CreateLWeapon( ReflectEWtype(ew->ID) );
lw->X = ew->X; lw->Y = ew->Y; lw->Z = ew->Z; lw->Jump = ew->Jump;
lw->DrawStyle = ew->DrawStyle; lw->OriginalTile = ew->OriginalTile; lw->Tile = ew->Tile;
lw->OriginalCSet = ew->OriginalCSet; lw->CSet = ew->CSet; lw->FlashCSet = ew->FlashCSet;
lw->NumFrames = ew->NumFrames; lw->Frame = ew->Frame; lw->ASpeed = ew->ASpeed;
lw->Damage = ew->Damage; lw->Step = ew->Step; lw->Angular = ew->Angular; lw->Flash = ew->Flash;
lw->DeadState = -1; lw->Flip = ew->Flip; lw->Extend = ew->Extend; lw->TileWidth = ew->TileWidth;
lw->TileHeight = ew->TileHeight; lw->HitWidth = ew->HitWidth; lw->HitHeight = ew->HitHeight;
lw->Dir = reverseDir(ew->Dir);
if(lw->Dir == DIR_UP) lw->Flip = 0;
else if(lw->Dir == DIR_DOWN) lw->Flip = 2;
else if(lw->Dir == DIR_RIGHT) lw->Flip = 0;
else if(lw->Dir == DIR_LEFT) lw->Flip = 1;
ew->DeadState = WDS_DEAD;
}//ifLinkHurt==2
else if(linkHurt == 3) damageLink = ew->Damage;
else if(linkHurt == 4) damageLink = ew->Damage * 0.5;
else if(linkHurt == 5) damageLink = ew->Damage * 0.25;
else if(linkHurt == 6) damageLink = ew->Damage * 2;
else if(linkHurt == 7) damageLink = ew->Damage * 3;
if(CGBShieldVars[CGBS_curDur] <= 0 || shieldHurt == 8) // shield destroyed (no durability left, or one-hit killed)
{
Game->PlaySound(SFX_SHIELDBREAK);
Link->Item[ CGBShieldVars[CGBS_curShieldItem] ] = false; //Remove real shield from Link inventory
Link->Item[ CGBShieldVars[CGBS_dummyShield] ] = false; //Remove dummy shield from Link inventory
itemdata dummy = Game->LoadItemData( CGBShieldVars[CGBS_dummyShield] ); // get our dummy shield data
CGBShieldVars[CGBS_DurSlot1 + dummy->InitD[3]] = 0; // clear this shield's durability slot (connected to its dummy)
for(int i=0;i<CGBS_DurSlot1;i++) CGBShieldVars[i]=0; // clear everything up to the saved durability slots
}//ifdestroyShield
if(damageLink>0) // we have to hurt Link
{
Link->HP -= damageLink;
Link->Action = LA_GOTHURTLAND;
Link->HitDir = -1;
Game->PlaySound(SFX_OUCH);
ew->DeadState = WDS_DEAD;
}//ifDamageLink>0
}//end Do_ConsumeShield
// converts an eweapon type to an lweapon when reflected off shield.
// does not currently include EW_SCRIPT#, EW_FIRE2. Could be added if desired.
int ReflectEWtype( int ewType){
if(ewType == EW_ARROW) return LW_ARROW;
if(ewType == EW_BRANG) return LW_BRANG;
if(ewType == EW_BEAM) return LW_REFBEAM;
if(ewType == EW_ROCK) return LW_REFROCK;
if(ewType == EW_MAGIC) return LW_REFMAGIC;
if(ewType == EW_FIREBALL || ewType == EW_FIREBALL2) return LW_REFFIREBALL;
if(ewType == EW_BOMB) return LW_BOMB;
if(ewType == EW_BOMBBLAST) return LW_BOMBBLAST;
if(ewType == EW_SBOMB) return LW_SBOMB;
if(ewType == EW_SBOMBBLAST) return LW_SBOMBBLAST;
if(ewType == EW_FIRE) return LW_FIRE;
if(ewType == EW_WIND) return LW_WIND;
return -1;
}
// convert an eweapon type value to the consumable shield values used by the CGBShieldVars[] array
int EWType_to_ConsumeShieldType(int ewType){
if(ewType == EW_ARROW) return CGBS_arrow;
if(ewType == EW_BRANG) return CGBS_boomr;
if(ewType == EW_BEAM) return CGBS_swordb;
if(ewType == EW_ROCK) return CGBS_rock;
if(ewType == EW_MAGIC) return CGBS_magic;
if(ewType == EW_FIREBALL) return CGBS_fireb;
if(ewType == EW_FIREBALL2) return CGBS_boss;
if(ewType == EW_BOMB) return CGBS_bomb;
if(ewType == EW_BOMBBLAST) return CGBS_bombb;
if(ewType == EW_SBOMB) return CGBS_sbomb;
if(ewType == EW_SBOMBBLAST) return CGBS_sbombb;
if(ewType == EW_FIRETRAIL) return CGBS_firet;
if(ewType == EW_FIRE) return CGBS_fire;
if(ewType == EW_WIND) return CGBS_wind;
if(ewType == EW_FIRE2) return CGBS_fire2;
if(ewType == EW_SCRIPT1) return CGBS_script1;
if(ewType == EW_SCRIPT2) return CGBS_script2;
if(ewType == EW_SCRIPT3) return CGBS_script3;
if(ewType == EW_SCRIPT4) return CGBS_script4;
if(ewType == EW_SCRIPT5) return CGBS_script5;
if(ewType == EW_SCRIPT6) return CGBS_script6;
if(ewType == EW_SCRIPT7) return CGBS_script7;
if(ewType == EW_SCRIPT8) return CGBS_script8;
if(ewType == EW_SCRIPT9) return CGBS_script9;
if(ewType == EW_SCRIPT10) return CGBS_script10;
return -1;
}//end EWType_to_ConsumeShieldType
// checks if our consumable shield cares about the eweapon type
bool CGBS_EWType( int ewType ){
if( CGBShieldVars[ EWType_to_ConsumeShieldType(ewType) ] > 0) return true;
return false;
}//end CGBS_EWType
// Grab the D values from the real shield item and sort them into the CGBShieldVars[] array for easier use
void Set_ShieldConsume(int shieldID)
{
float defenseTypes = 0;
int defenseVal = 0;
bool isNeg;
itemdata shield = Game->LoadItemData(shieldID);
// if we didn't have a saved durability for this shield, we get the durability for it being brand spankin new
if( CGBShieldVars[CGBS_curDur] <= 0) CGBShieldVars[CGBS_curDur] = shield->InitD[0];
for(int i=1;i<8;i++) // cycle the remaining arguments
{
defenseTypes = shield->InitD[i];
if(defenseTypes==0) continue; // no inputted value for the argument, move onto next
isNeg = (defenseTypes<0);
if(isNeg) defenseTypes = Abs(defenseTypes);
// next two statements separate the integer and fraction from the argument into two variables
defenseVal = (defenseTypes - Floor(defenseTypes) ) * 100;
defenseTypes = Floor(defenseTypes);
if(isNeg) // we are using a speciality shield defense value
{
CGBShieldVars[defenseTypes] = defenseVal;
}
else // we are just using the standard shield defense bit flag values
{
for(int b=1;b<10;b++) // cycle through the bits of the shield defense argument
{
// if the bit is true (we have defense to that weapon) set the corresponding defense value to our CGBShieldVars[] array
if( GetBit(defenseTypes,b) == true ) CGBShieldVars[b] = defenseVal;
}//for loop
}//else statement
}//for loop
}//Set_ShieldConsume
//---------------------
// General functions
int SetBit(int vari, int bit, bool state){
bit = bit-1;
int r = vari;
if(state) r |= (1 << bit);
else r &= ~(1 << bit);
return r;
}
bool GetBit(int vari, int bit){
bit = bit-1;
return (vari & (1 << bit)) != 0;
}
//from stdExtra.zh remove this if you have stdExtra.zh imported.
//Returns the reverse of the given direction.
int reverseDir(int dir)
{
if(dir != Clamp(dir, 0, 15)) return -1; //Invalid direction
return Cond(dir<8, OppositeDir(dir), ((dir+4)%8)+8);
}
void TestInt(int num, int x, int y) {
Screen->DrawInteger(0,x,y,0,0,-1,0,0,num,0,OP_OPAQUE);
}
// ---------------------------------------
// the following constants do not need to be changed. they are indexes to the variables of the CGBShieldVars[] array
// however, if your quest is using more than 5 consumable shields, you will need to increase the size of the array. see the bottom of this list for the formula.
const int CGBS_curDur = 0; // index to current shield's current durability
const int CGBS_rock = 1; // index to eweapon rock defenses
const int CGBS_arrow = 2; // index to eweapon arrow defenses
const int CGBS_boomr = 3; // index to eweapon boomerang defenses
const int CGBS_fireb = 4; // index to eweapon fireball defenses
const int CGBS_swordb = 5; // index to eweapon sword beam defenses
const int CGBS_magic = 6; // index to eweapon magic defenses
const int CGBS_fire = 7; // index to eweapon fire defenses
const int CGBS_script = 8; // index to eweapon generic script defenses
const int CGBS_boss = 9; // index to eweapon boss fireball defenses
const int CGBS_bomb = 10; // index to eweapon projectile bomb defenses
const int CGBS_bombb = 11; // index to eweapon bomb blast defenses
const int CGBS_sbomb = 12; // index to eweapon projectile superbomb defenses
const int CGBS_sbombb = 13; // index to eweapon superbomb blast defenses
const int CGBS_firet = 14; // index to eweapon fire trail defenses
const int CGBS_wind = 15; // index to eweapon wind defenses
const int CGBS_fire2 = 16; // index to eweapon fire2 defenses
const int CGBS_script1 = 17; // index to eweapon script# defenses
const int CGBS_script2 = 18;
const int CGBS_script3 = 19;
const int CGBS_script4 = 20;
const int CGBS_script5 = 21;
const int CGBS_script6 = 22;
const int CGBS_script7 = 23;
const int CGBS_script8 = 24;
const int CGBS_script9 = 25;
const int CGBS_script10 = 26;
const int CGBS_curShieldItem = 27; // index to current real shield item# being tracked
const int CGBS_dummyShield = 28; // index to the dummy shield item# that controls the real shield
const int CGBS_Button = 29; // index to a variable tracking the button press that actuates the shield (A==2, B==1)
const int CGBS_shieldOn = 30; // index to a variable tracking the real shield is being used
const int CGBS_usedDummy = 31; // index to a variable tracking the one-frame usage of the dummy item to tell the global script to give the real shield
const int CGBS_DurSlot1 = 32; // from this array value and up can be used to save durability of multiple shields
// DurSlot2 = 33, DurSlot3 = 34, DurSlot4 = 35, DurSlot5= 36
// if you need to save more than 5 shield durabilities increase the CGBShieldVars[] array using the following formula
// (total number of slots) + CGBS_DurSlot1
// eg currently CGBShieldVars[37] (number of slots = 5) + (CGBS_DurSlot1 = 32) = 37
// ------------------- end of script file -----------------------
const int SCRIPT_BARRIERS = 1; // Must refer to "Barrier"'s ffc script slot in the quest
// ID's of barrier-related combos
// Barriers in raised state
const int BARRIER_A_RAISED = 32;
const int BARRIER_B_RAISED = 33;
// Barriers in lowered state
const int BARRIER_A_LOWERED = 34;
const int BARRIER_B_LOWERED = 35;
// Barriers animating to raised state
const int BARRIER_A_ANIMRAISE = 36;
const int BARRIER_B_ANIMRAISE = 37;
// Barriers animating to lowered state
const int BARRIER_A_ANIMLOWER = 38;
const int BARRIER_B_ANIMLOWER = 39;
// Raised barriers that Link can walk on
const int BARRIER_A_WALKABLE = 40;
const int BARRIER_B_WALKABLE = 41;
// Barrier switches
const int BARRIER_A_SWITCH = 42;
const int BARRIER_B_SWITCH = 43;
const int BARRIER_SWITCH_DUMMY = 177; // ID of a switch hit detection dummy enemy
const int BARRIER_SWITCH_DUMMY_HP = 32767;
// Global array to store the state of barriers per dmap
// If you have more than 16 dmaps you can change the capacity in the []'s
// You may change the states in other scripts, but the changes will not be visible
// until there is a new screen, so set them before Barriers_NewScreen() is called.
bool barriers[16]; // false = blue barriers raised, true = red barriers raised
global script slot2 {
void run() {
// Initialize variables used to listen on screen changes
int curscreen = -1;
while (true) {
// Keep track of screen changes
// Run a Barrier script on every screen change
if (Game->GetCurScreen() != curscreen) {
curscreen = Game->GetCurScreen();
Barriers_NewScreen();}
Waitframe();}}}
// Function that makes preparations for barriers on each screen and starts an FFC script
void Barriers_NewScreen() {
// Search for a barrier-related combo
for (int i = 0; i <= 175; i++) {
int cd = Screen->ComboD[i];
if (cd == BARRIER_A_RAISED || cd == BARRIER_A_LOWERED || cd == BARRIER_A_SWITCH ||
cd == BARRIER_B_RAISED || cd == BARRIER_B_LOWERED || cd == BARRIER_B_SWITCH) {
// A barrier-related combo was found
// Make initial changes to combos
if (barriers[Game->GetCurDMap()]) {
for (int j = i; j <= 175; j++) {
int cd = Screen->ComboD[j];
if (cd == BARRIER_A_RAISED) Screen->ComboD[j] = BARRIER_A_LOWERED;
else if (cd == BARRIER_B_LOWERED) Screen->ComboD[j] = BARRIER_B_RAISED;
else if (cd == BARRIER_A_SWITCH) Screen->ComboD[j] = BARRIER_B_SWITCH;}}
else {
for (int j = i; j <= 175; j++) {
int cd = Screen->ComboD[j];
if (cd == BARRIER_B_RAISED) Screen->ComboD[j] = BARRIER_B_LOWERED;
else if (cd == BARRIER_A_LOWERED) Screen->ComboD[j] = BARRIER_A_RAISED;
else if (cd == BARRIER_B_SWITCH) Screen->ComboD[j] = BARRIER_A_SWITCH;}}
// So run FFCscript to control barriers
int args[] = {0,0,0,0,0,0,0,0};
RunFFCScript(SCRIPT_BARRIERS, args);
break;}
}}
// This lets you toggle barriers on any dmap
bool ToggleBarriers(int dmap) {
if (dmap == Game->GetCurDMap()) ToggleBarriers();
else barriers[dmap] = !barriers[dmap];
return barriers[dmap];}
// This toggles barriers on the current dmap
bool ToggleBarriers() {
int curdmap = Game->GetCurDMap();
if (!barriers[curdmap]) {
barriers[curdmap] = true;
for (int i = 0; i <= 175; i++) {
int cd = Screen->ComboD[i];
if (cd == BARRIER_A_RAISED || cd == BARRIER_A_WALKABLE || cd == BARRIER_A_ANIMRAISE) {
Screen->ComboD[i] = BARRIER_A_ANIMLOWER;}
else if (cd == BARRIER_B_LOWERED || cd == BARRIER_B_ANIMLOWER) {
Screen->ComboD[i] = BARRIER_B_ANIMRAISE;}
else if (cd == BARRIER_A_SWITCH) {Screen->ComboD[i] = BARRIER_B_SWITCH;}}}
else {
barriers[curdmap] = false;
for (int i = 0; i <= 175; i++) {
int cd = Screen->ComboD[i];
if (cd == BARRIER_B_RAISED || cd == BARRIER_B_WALKABLE || cd == BARRIER_B_ANIMRAISE) {
Screen->ComboD[i] = BARRIER_B_ANIMLOWER;}
else if (cd == BARRIER_A_LOWERED || cd == BARRIER_A_ANIMLOWER) {
Screen->ComboD[i] = BARRIER_A_ANIMRAISE;}
else if (cd == BARRIER_B_SWITCH) {Screen->ComboD[i] = BARRIER_A_SWITCH;}}}
return barriers[curdmap];
}
// This script controls barriers on the screen
// The FFC is automatically created by Barriers_NewScreen()
ffc script Barriers {
void run() {
// Initialize storage for bswitch hit dummies
int bswitch_count;
npc bswitch[8];
for (int i = 0; i <= 175; i++) {
if (Screen->ComboD[i] == BARRIER_A_SWITCH || Screen->ComboD[i] == BARRIER_B_SWITCH) {
npc bs = CreateNPCAt(BARRIER_SWITCH_DUMMY, ComboX(i), ComboY(i));
bs->HitWidth = 8; // Smaller hit box to avoid annoying collisions with Link
bs->HitHeight = 8;
bs->HP = BARRIER_SWITCH_DUMMY_HP;
bswitch[bswitch_count++] = bs;}}
// Change raised barriers to walkable ones if Link enters screen on a raised barrier
int lcombo = LinkOnComboD();
bool onbarrier = (lcombo == BARRIER_A_RAISED || lcombo == BARRIER_B_RAISED);
if (onbarrier) for (int i = 0; i < 176; i++) {
if (Screen->ComboD[i] == BARRIER_A_RAISED) {Screen->ComboD[i] = BARRIER_A_WALKABLE;}
else if (Screen->ComboD[i] == BARRIER_B_RAISED) {Screen->ComboD[i] = BARRIER_B_WALKABLE;}}
while (true) {
// Detect hits on bswitches, and change combos accordingly
for (int j = 0; j < bswitch_count; j++) {
if (bswitch[j]->HP < BARRIER_SWITCH_DUMMY_HP) {
bswitch[j]->HP = BARRIER_SWITCH_DUMMY_HP;
ToggleBarriers();
break;}} //break so that only one bswitch hit may register per frame
// Make barriers walkable if Link is on raised barriers, or unwalkable if not
lcombo = LinkOnComboD();
if (!onbarrier && (lcombo == BARRIER_A_RAISED || lcombo == BARRIER_B_RAISED)) {
onbarrier = true;
for (int i = 0; i <= 175; i++) {
if (Screen->ComboD[i] == BARRIER_A_RAISED) {Screen->ComboD[i] = BARRIER_A_WALKABLE;}
else if (Screen->ComboD[i] == BARRIER_B_RAISED) {Screen->ComboD[i] = BARRIER_B_WALKABLE;}}}
else if (onbarrier && !(lcombo == BARRIER_A_WALKABLE || lcombo == BARRIER_B_WALKABLE)) {
onbarrier = false;
for (int i = 0; i <= 175; i++) {
if (Screen->ComboD[i] == BARRIER_A_WALKABLE) {Screen->ComboD[i] = BARRIER_A_RAISED;}
else if (Screen->ComboD[i] == BARRIER_B_WALKABLE) {Screen->ComboD[i] = BARRIER_B_RAISED;}}}
Waitframe();}
}}
// A utility function that returns the ID of the combo that Link appears to stand on
int LinkOnComboD() {
return Screen->ComboD[ComboAt(Link->X+8, Link->Y+13)];
}
////////////////////////////////////////////////////////////////
// Overhead
// by grayswandir
////////////////////////////////////////////////////////////////
// Makes certain overhead layers transparent/invisible while link is
// underneath them.
////////////////////////////////////////////////////////////////
// Setup:
// Put Overhead_Update() in your active loop.
// Mess with the Configuration section if you want.
////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////
// Configuration
// Set to 1 to make the tiles disappear completely, instead of being drawn
// transparently.
const int OVERHEAD_INVISIBLE = 0;
// These are the layers that are used. Set to 1 to enable, and 0 to disable.
const int OVERHEAD_USE_L3 = 0;
const int OVERHEAD_USE_L4 = 0;
const int OVERHEAD_USE_L5 = 1;
const int OVERHEAD_USE_L6 = 1;
// Change this to 16 if you have very fast scrolling turned on.
const int OVERHEAD_SCROLL_SPEED = 4;
////////////////////////////////////////////////////////////////
// Code
int Overhead_Data[1416];
const int OVERHEAD_STATE = 0;
const int OVERHEAD_LAST_SCREEN = 1;
const int OVERHEAD_SCROLL_DIR = 2;
const int OVERHEAD_TIMER = 3;
const int OVERHEAD_SCREENS = 4;
const int OVERHEAD_COMBOS = 8;
const int OVERHEAD_CSETS = 712;
const int OVERHEAD_STATE_UNINIT = 0;
const int OVERHEAD_STATE_SCROLLING = 1;
const int OVERHEAD_STATE_WORKING = 2;
void Overhead_Update() {
int map; int screen; int location; int layer; bool under; int offset;
// If this is the first time this function has been called, do some setup.
if (OVERHEAD_STATE_UNINIT == Overhead_Data[OVERHEAD_STATE]) {
Overhead_Data[OVERHEAD_STATE] = OVERHEAD_STATE_SCROLLING;
Overhead_Data[OVERHEAD_LAST_SCREEN] = -1;
for (layer = 3; layer <= 6; ++layer) {
Overhead_Data[OVERHEAD_SCREENS + layer - 3] = -1;
}
}
// If we've left our current screen, reset the layers we killed.
screen = (Game->GetCurMap() << 8) + Game->GetCurScreen();
if (screen != Overhead_Data[OVERHEAD_LAST_SCREEN]) {
for (layer = 3; layer <= 6; ++layer) {
// Skip if this layer wasn't recorded.
if (-1 == Overhead_Data[OVERHEAD_SCREENS + layer - 3]) {continue;}
// Replace the lost data.
map = Overhead_Data[OVERHEAD_SCREENS + layer - 3] >> 8;
screen = Overhead_Data[OVERHEAD_SCREENS + layer - 3] % 256;
offset = 176 * (layer - 3);
for (location = 0; location < 176; ++location) {
Game->SetComboData(map, screen, location, Overhead_Data[OVERHEAD_COMBOS + offset + location]);
}
}
// Remember what screen we're on, so we can tell if we've moved.
Overhead_Data[OVERHEAD_LAST_SCREEN] = (Game->GetCurMap() << 8) + Game->GetCurScreen();
Overhead_Data[OVERHEAD_STATE] = OVERHEAD_STATE_SCROLLING;
// If we've just started scrolling, figure out what direction it's in so
// we can draw the deleted combos properly. Also reset the timer.
if (LA_SCROLLING == Link->Action) {
if (-16 == Link->X) {Overhead_Data[OVERHEAD_SCROLL_DIR] = DIR_RIGHT;}
if (256 == Link->X) {Overhead_Data[OVERHEAD_SCROLL_DIR] = DIR_LEFT;}
if (-16 == Link->Y) {Overhead_Data[OVERHEAD_SCROLL_DIR] = DIR_DOWN;}
if (176 == Link->Y) {Overhead_Data[OVERHEAD_SCROLL_DIR] = DIR_UP;}
Overhead_Data[OVERHEAD_TIMER] = 0;
}
}
// If we've finished scrolling, copy over the layers and delete them.
if (LA_SCROLLING != Link->Action && OVERHEAD_STATE_SCROLLING == Overhead_Data[OVERHEAD_STATE]) {
for (layer = 3; layer <= 6; ++layer) {
// Skip this layer if we're not configured to use it.
if (3 == layer && !OVERHEAD_USE_L3) {continue;}
if (4 == layer && !OVERHEAD_USE_L4) {continue;}
if (5 == layer && !OVERHEAD_USE_L5) {continue;}
if (6 == layer && !OVERHEAD_USE_L6) {continue;}
// If this screen doesn't use this layer, mark as not in use and skip.
map = Screen->LayerMap(layer);
screen = Screen->LayerScreen(layer);
if (-1 == map || -1 == screen) {
Overhead_Data[OVERHEAD_SCREENS + layer - 3] = -1;
continue;
}
// Save this layer's screen location.
Overhead_Data[OVERHEAD_SCREENS + layer - 3] = (map << 8) + screen;
// Grab every combo and cset, and delete the original.
offset = (layer - 3) * 176;
for (location = 0; location < 176; ++location) {
// Grab the data.
Overhead_Data[OVERHEAD_COMBOS + offset + location] = Game->GetComboData(map, screen, location);
Overhead_Data[OVERHEAD_CSETS + offset + location] = Game->GetComboCSet(map, screen, location);
// Delete the original.
Game->SetComboData(map, screen, location, 0);
}
}
// Update the state so we know we've copied the data.
Overhead_Data[OVERHEAD_STATE] = OVERHEAD_STATE_WORKING;
}
// See if link is standing under a combo in one of the specified layers.
under = false;
location = ComboAt(Link->X + 8, Link->Y + 8);
for (layer = 3; layer <= 6; ++layer) {
// Skip this layer if it's not in use.
if (-1 == Overhead_Data[OVERHEAD_SCREENS + layer - 3]) {continue;}
// Check for there being a non-0 combo at the specified position.
if (Overhead_Data[OVERHEAD_COMBOS + (layer - 3) * 176 + location]) {
under = true;
break;
}
}
// Offsets for scrolling.
int x = 0;
int y = 0;
if (OVERHEAD_STATE_SCROLLING == Overhead_Data[OVERHEAD_STATE]) {
if (DIR_LEFT == Overhead_Data[OVERHEAD_SCROLL_DIR]) {x = Overhead_Data[OVERHEAD_TIMER];}
if (DIR_RIGHT == Overhead_Data[OVERHEAD_SCROLL_DIR]) {x = -Overhead_Data[OVERHEAD_TIMER];}
if (DIR_UP == Overhead_Data[OVERHEAD_SCROLL_DIR]) {y = Overhead_Data[OVERHEAD_TIMER];}
if (DIR_DOWN == Overhead_Data[OVERHEAD_SCROLL_DIR]) {y = -Overhead_Data[OVERHEAD_TIMER];}
Overhead_Data[OVERHEAD_TIMER] += OVERHEAD_SCROLL_SPEED;
}
// Don't draw if we're under and have it set to be invisible then.
if (under && OVERHEAD_INVISIBLE) {return;}
// Draw the overhead layers.
int opaque = Cond(under, OP_TRANS, OP_OPAQUE);
for (layer = 3; layer <= 6; ++layer) {
// Make sure the layer exists.
if (-1 == Overhead_Data[OVERHEAD_SCREENS + layer - 3]) {continue;}
// Draw the layer.
offset = (layer - 3) * 176;
for (location = 0; location < 176; ++location) {
int combo = Overhead_Data[OVERHEAD_COMBOS + offset + location];
if (combo) {
Screen->FastCombo(layer, ComboX(location) + x, ComboY(location) + y,
combo, Overhead_Data[OVERHEAD_CSETS + offset + location],
opaque);
}
}
}
}
// uncomment this line (remove the //) if you haven't already imported std.zh in your script file
//import "std.zh"
int BetterByrna[8];
const int BETTERBYRNA_COST = 0;
const int BETTERBYRNA_MP_TRACKER = 1;
const int BETTERBYRNA_INVINCIBLE = 2;
const int BETTERBYRNA_BLOCK_PROJECTILES = 3;
global script BetterByrnaSampleGlobal
{
void run()
{
while (true)
{
BetterByrna();
Waitdraw();
Waitframe();
}
}
}
void BetterByrna()
{
if (NumLWeaponsOf(LW_CANEOFBYRNA) > 0)
{
// make player invincible
if (Link->CollDetection && BetterByrna[BETTERBYRNA_INVINCIBLE])
{
Link->CollDetection = false;
}
// deduct MP cost
if (BetterByrna[BETTERBYRNA_MP_TRACKER] >= 1)
{
if (Link->MP - Floor(BetterByrna[BETTERBYRNA_MP_TRACKER]) >= 0)
{
Link->MP -= Floor(BetterByrna[BETTERBYRNA_MP_TRACKER]);
}
else
{
Link->MP = 0;
}
BetterByrna[BETTERBYRNA_MP_TRACKER] -= Floor(BetterByrna[BETTERBYRNA_MP_TRACKER]);
}
if (Link->MP == 0)
{
lweapon byrna = LoadLWeaponOf(LW_CANEOFBYRNA);
Remove(byrna);
}
else
{
BetterByrna[BETTERBYRNA_MP_TRACKER] += BetterByrna[BETTERBYRNA_COST] * (Game->Generic[GEN_MAGICDRAINRATE] * 0.5);
}
// block projectiles
if (BetterByrna[BETTERBYRNA_BLOCK_PROJECTILES])
{
for (int i = Screen->NumEWeapons(); i > 0; i--)
{
eweapon projectile = Screen->LoadEWeapon(i);
if (projectile->ID != EW_BOMBBLAST && projectile->ID != EW_SBOMBBLAST)
{
for (int j = Screen->NumLWeapons(); j > 0; j--)
{
lweapon byrna = Screen->LoadLWeapon(j);
if (byrna->ID == LW_CANEOFBYRNA && Collision(projectile, byrna))
{
Remove(projectile);
}
}
}
}
}
}
// make player vulnerable again
else if (!Link->CollDetection)
{
Link->CollDetection = true;
}
if (Link->MP == 0 && (Link->InputA || Link->InputB))
{
itemdata a_button = Game->LoadItemData(GetEquipmentA());
itemdata b_button = Game->LoadItemData(GetEquipmentB());
if (Link->InputA && a_button->Family == IC_CBYRNA)
{
Link->InputA = false;
Link->PressA = false;
}
if (Link->InputB && b_button->Family == IC_CBYRNA)
{
Link->InputB = false;
Link->PressB = false;
}
}
}
this is a long file
// D0: reserved for other things, like pickup message scripts
// D1: MP cost per frame
// D2: 1 for invincible while cane is in use
// D3: 1 to block enemy projectiles
item script BetterByrnaItem
{
void run(int foo, int cost, int invincible, int block_projectiles)
{
BetterByrna[BETTERBYRNA_COST] = cost;
BetterByrna[BETTERBYRNA_INVINCIBLE] = invincible;
BetterByrna[BETTERBYRNA_BLOCK_PROJECTILES] = block_projectiles;
}
}
const int CUSTOM_LENS_HINTS_MAX_LAYERS = 0; //Maximum layers to check screens for lens hints
//Global script example.
global script LensHints{
void run (){
while (true){
Waitdraw();
DrawCustomLensHints();
Waitframe();
}
}
}
//Main custom lens hint drawing function. Put this into main loop of "Action" global script.
void DrawCustomLensHints(){
if (Link->MP<=0) return;
if (!UsingItem(I_LENS))return;
//Add lens hints here.
DrawCustomLensHint(0, 120, 1028, 8, 1);//Draw combo#1028 with cset 8 on all combos of type 120 (damage 8 hearts)
DrawCustomLensHint(1, 98, 1029, 7, 1);//Draw combo#1029 with cset 7 on all combos with inherent or placed flag 98 (Script 1)
DrawCustomLensHint(2, 55, 1030, 6, 1);//Draw combo#1030 with cset 6 on all NPC`s with ID#55 (Arrow Pols Voices)
//Add more lens hints here.
}
//Lenstype: 0-combo type, 1-combo flag, 2 - NPC.
//miscvalue1: depends on lenstype:
// 0 - combo type ID
// 1 - combo flag ID
// 2 - NPC ID
//cmb - combo to draw, cset - cset to use for hint drawing
//minlevel - minimum item level for Lens-like item needed to be used to reveal this hint.
void DrawCustomLensHint(int lenstype, int miscvalue1, int cmb, int cset, int minlevel){
int lens = GetCurrentItem(IC_LENS);
itemdata it = Game->LoadItemData(lens);
if (it->Level<minlevel) return;
if (lenstype==0){//combo types
for (int l=0; l<=CUSTOM_LENS_HINTS_MAX_LAYERS; l++){
if (l==0){
for (int c=0;c<176;c++){
if (Screen->ComboT[c]==miscvalue1) Screen->FastCombo(0, ComboX(c), ComboY(c), cmb, cset, OP_OPAQUE);
}
if ((Screen->LayerMap(l)==-1)||(Screen->LayerScreen(l)==-1))continue;
for (int c=0;c<176;c++){
int lc = GetLayerComboT(l, c);
if (Screen->ComboT[lc]==miscvalue1) Screen->FastCombo(l, ComboX(lc), ComboY(lc), cmb, cset, OP_OPAQUE);
}
}
}
return;
}
else if (lenstype==1){//combo flags
for (int l=0; l<=CUSTOM_LENS_HINTS_MAX_LAYERS; l++){
if (l==0){
for (int c=0;c<176;c++){
if (ComboFI(c, miscvalue1)) Screen->FastCombo(0, ComboX(c), ComboY(c), cmb, cset, OP_OPAQUE);
}
if ((Screen->LayerMap(l)==-1)||(Screen->LayerScreen(l)==-1))continue;
for (int c=0;c<176;c++){
int lc = GetLayerComboT(l, c);
if (ComboFI(lc, miscvalue1)) Screen->FastCombo(l, ComboX(lc), ComboY(lc), cmb, cset, OP_OPAQUE);
}
}
}
return;
}
else if (lenstype==2){//enemies
for (int i=1; i<= Screen->NumNPCs(); i++ ){
npc lensie= Screen->LoadNPC(i);
if (lensie->ID==miscvalue1) Screen->FastCombo(6, lensie->X, lensie->Y-lensie->Z, cmb, cset, OP_OPAQUE);
}
}
}
//Draws Lens hints on FFC`s if FFC runs given script and has specific value set in checked Init D variable.
void DrawFFCLensHint(int scr, int dreg, int dvalue, int cmb, int cset, int minlevel){
int lens = GetCurrentItem(IC_LENS);
itemdata it = Game->LoadItemData(lens);
if (it->Level<minlevel) return;
for (int i=1;i<=32;i++){
ffc lensie = Screen->LoadFFC(i);
if (lensie->Script!=scr) continue;
if (lensie->InitD[dreg]!=dvalue) continue;
Screen->FastCombo(0, CenterX(lensie), CenterY(lensie), cmb, cset, OP_OPAQUE);
}
}
//FFC version of custom lens hints.
//D0 - Lenstype: 0-combo type, 1-combo flag, 2 - NPC.
//D1: depends on lenstype:
// 0 - combo type ID
// 1 - combo flag ID
// 2 - NPC ID
//D2 - combo to draw,
//D3 - cset to use for hint drawing
//D4 - minimum item level for Lens-like item needed to be used to reveal this hint.
ffc script CustomLensHints{
void run (int lenstype, int miscvalue1, int cmb, int cset, int minlevel){
while (true){
DrawCustomLensHint(lenstype, miscvalue1, cmb, cset, minlevel);
Waitframe();
}
}
}
//X--------------------X
//| Bottle Constants |
//X--------------------X
const int FFC_SFA = 31; //FFC used for screen freeze A
const int FFC_SFB = 32; //FFC used for screen freeze B
const int CMB_SFA = 2; //Combo used for screen freeze A
const int CMB_SFB = 3; //Combo used for screen freeze B
const int BOTTLE_SETTING_NO_WATER = 0; //Set to 1 if water shouldn't be bottleable
const int TIL_BOTTLE = 52020; //First of the tiles used for the bottle items. Should come in four identical rows.
//Tile order in each row should go as such:
//Empty, Empty, Red Potion, Green Potion, Blue Potion, Water, Fairy, Bee
const int REDPOTION_HEARTS = 8; //Hearts the red potion heals
const int GREENPOTION_MP = 256; //MP the green potion restores
const int BLUEPOTION_HEARTS = 16; //Hearts the blue potion heals
const int BLUEPOTION_MP = 256; //MP the blue potion restores
const int LW_WATER = 31; //LWeapon type used for bottled water. Script 1 by default
const int SPR_BOTTLEWATER = 88; //Sprite used for bottled water
const int SFX_BOTTLEWATER = 55; //Sound when water is dumped out
const int FAIRY_HEARTS = 3; //Hearts healed by a fairy
const int CMB_FAIRY = 904; //Fairy combo
const int CS_FAIRY = 8; //Fairy cset
const int SFX_FAIRY = 64; //Sound that plays when a fairy appears
const int IC_BOTTLE = 67; //Item class used for bottles. Custom 1 by default.
const int I_BOTTLE1 = 143; //Item ID for the first bottle (Level 1)
const int I_BOTTLE2 = 144; //Item ID for the second bottle (Level 2)
const int I_BOTTLE3 = 145; //Item ID for the second bottle (Level 3)
const int I_BOTTLE4 = 146; //Item ID for the second bottle (Level 4)
const int FREQ_HEARTREFILL = 8; //Frequency in frames at which potions/fairies restore hearts
const int SFX_HEARTREFILL = 22; //Sound when potion/fairy restores a heart
const int FREQ_MAGICSOUND = 8; //Frequency in frames where the magic refill sound plays
const int SFX_MAGICREFILL = 61; //Magic refill sound
const int SFX_ERROR = 62; //Error sound
const int TIL_BOTTLESWING = 52006; //Tile of a right facing open bottle used when trying to catch something
const int CS_BOTTLESWING = 11; //CSet of the swinging bottle
const int SFX_BOTTLESWING = 63; //Sound used for the bottle being swung
const int I_WATERBOTTLE = 150; //Item for bottle water pickup
const int I_FAIRYBOTTLE = 151; //Item for bottle fairy pickup
const int I_BEEBOTTLE = 152; //Item for bottle bee pickup
const int CMB_BEE = 905; //Combo used for the bee
const int CS_BEE = 8; //CSet used for the bee
const int SFX_BEE = 65; //SFX used for the bee
const int LW_BEE = 32; //Lweapon used for the bee (Script 2 by default)
const int EW_BEE = 32; //Eweapon used for the bee (Script 2 by default)
const int DAMAGE_BEE = 4; //Damage the bee deals
const int FFCM_BEE_SELFDESTRUCT = 0; //FFC misc used to tell the bee to disappear
const int STR_CANTAFFORD = 2; //Message for when you can't afford an item
const int STR_NOBOTTLE = 3; //Message for when you don't have a bottle to store a potion in
const int C_WHITE = 0x01; //The color white
const int C_BLACK = 0x0F; //The color black
//X--------------------------X
//| Screen Freeze Function |
//X--------------------------X
void Screen_Freeze(){
ffc f1 = Screen->LoadFFC(FFC_SFA);
ffc f2 = Screen->LoadFFC(FFC_SFB);
f1->Data = CMB_SFA;
f2->Data = CMB_SFB;
}
void Screen_Unfreeze(){
ffc f1 = Screen->LoadFFC(FFC_SFA);
ffc f2 = Screen->LoadFFC(FFC_SFB);
f1->Data = 0;
f2->Data = 0;
}
//X--------------------------X
//| Empty Bottle Functions |
//X--------------------------X
//X--------------------------------------------------------X
//| These constants don't need to be changed. |
//| They just define various states of the empty bottle. |
//| BS_ constants are also used for the potion filling |
//| pickup item script. Look here to see what to set D2 |
//| to for that. |
//X--------------------------------------------------------X
// |
const int BS_EMPTY = 0; // |
const int BS_POTIONRED = 1; // |
const int BS_POTIONGREEN = 2; // |
const int BS_POTIONBLUE = 3; // |
const int BS_WATER = 4; // |
const int BS_FAIRY = 5; // |
const int BS_BEE = 6; // |
// |
const int BSI_BOTTLEUSED = 4; // |
const int BSI_BOTTLETIMER = 5; // |
const int BSI_OLDHP = 6; // |
const int BSI_OLDMP = 7; // |
const int BSI_FAIRYTIMER = 8; // |
const int BSI_FAIRYREVIVE = 9; // |
// |
//---------------------------------------------------------X
int BottleState[12]; //0-3: States of bottles, 4: Bottle used,
//5: Potion timer, 6: OldHP, 7: OldMP
//This function should be called at the beginning of your global and
//refreshes the graphics for the bottles.
void RefreshBottles(){
for(int i=0; i<4; i++){
CopyTile(TIL_BOTTLE+20*i+1+BottleState[i], TIL_BOTTLE+20*i);
}
}
int UsingEmptyBottle(){
if(Link->PressA){
int id = GetEquipmentA();
if(id>0){
itemdata A = Game->LoadItemData(id);
if(A->Family==IC_BOTTLE)
return A->Level-1;
}
}
else if(Link->PressB){
int id = GetEquipmentB();
if(id>0){
itemdata B = Game->LoadItemData(id);
if(B->Family==IC_BOTTLE)
return B->Level-1;
}
}
return -1;
}
bool CanFillBottle(){
int bottles[4] = {I_BOTTLE1, I_BOTTLE2, I_BOTTLE3, I_BOTTLE4};
for(int i=0; i<4; i++){
if(Link->Item[bottles[i]]&&BottleState[i]==BS_EMPTY)
return true;
}
return false;
}
int FillBottle(int state){
int bottles[4] = {I_BOTTLE1, I_BOTTLE2, I_BOTTLE3, I_BOTTLE4};
for(int i=0; i<4; i++){
if(Link->Item[bottles[i]]&&BottleState[i]==BS_EMPTY){
BottleState[i] = state;
RefreshBottles();
return i;
}
}
}
int HasFairy(){
int bottles[4] = {I_BOTTLE1, I_BOTTLE2, I_BOTTLE3, I_BOTTLE4};
for(int i=0; i<4; i++){
if(Link->Item[bottles[i]]&&BottleState[i]==BS_FAIRY)
return i;
}
return -1;
}
//This function goes in the while loop of your global script before waitdraw
void EmptyBottleGlobal(){
int bottle = BottleState[BSI_BOTTLEUSED];
if(BottleState[BSI_BOTTLETIMER]>0){
if(BottleState[bottle]==BS_POTIONRED){
if(BottleState[BSI_BOTTLETIMER]%FREQ_HEARTREFILL==0){
Link->HP += 16;
Game->PlaySound(SFX_HEARTREFILL);
if(Link->HP>=Link->MaxHP){
BottleState[BSI_BOTTLETIMER] = 0;
}
}
}
else if(BottleState[bottle]==BS_POTIONGREEN){
Link->MP += 2;
if(BottleState[BSI_BOTTLETIMER]%FREQ_MAGICSOUND==0)
Game->PlaySound(SFX_MAGICREFILL);
if(Link->MP>=Link->MaxMP){
BottleState[BSI_BOTTLETIMER] = 0;
}
}
else if(BottleState[bottle]==BS_POTIONBLUE){
if(BottleState[BSI_BOTTLETIMER]%FREQ_HEARTREFILL==0&&Link->HP<BottleState[BSI_OLDHP]+BLUEPOTION_HEARTS*16&&Link->HP<Link->MaxHP){
Link->HP += 16;
Game->PlaySound(SFX_HEARTREFILL);
}
if(Link->MP<BottleState[BSI_OLDMP]+BLUEPOTION_MP&&Link->MP<Link->MaxMP){
if(BottleState[BSI_BOTTLETIMER]%FREQ_MAGICSOUND==0)
Game->PlaySound(SFX_MAGICREFILL);
Link->MP += 2;
}
if(Link->HP>=Link->MaxHP&&Link->MP>=Link->MaxMP){
BottleState[BSI_BOTTLETIMER] = 0;
}
}
else if(BottleState[bottle]==BS_FAIRY){
if(BottleState[BSI_BOTTLETIMER]<2&&BottleState[BSI_FAIRYTIMER]<120)
BottleState[BSI_BOTTLETIMER] = 2;
BottleState[BSI_FAIRYTIMER]++;
int X = Link->X+VectorX(16*(BottleState[BSI_FAIRYTIMER]/120), BottleState[BSI_FAIRYTIMER]*8);
int Y = Link->Y+VectorY(8*(BottleState[BSI_FAIRYTIMER]/120), BottleState[BSI_FAIRYTIMER]*8)-BottleState[BSI_FAIRYTIMER]/8;
if(BottleState[BSI_FAIRYREVIVE]==1){
if(BottleState[BSI_FAIRYTIMER]<10||BottleState[BSI_FAIRYTIMER]>110)
Screen->Rectangle(6, 0, 0, 256, 176, C_BLACK, 1, 0, 0, 0, true, 64);
else
Screen->Rectangle(6, 0, 0, 256, 176, C_BLACK, 1, 0, 0, 0, true, 128);
Screen->FastTile(6, Link->X+Link->DrawXOffset, Link->Y+Link->DrawYOffset, Link->Tile, 6, 128);
}
if(BottleState[BSI_FAIRYTIMER]<80||BottleState[BSI_FAIRYTIMER]%2==0)
Screen->FastCombo(6, X, Y, CMB_FAIRY, CS_FAIRY, 128);
if(BottleState[BSI_BOTTLETIMER]%FREQ_HEARTREFILL==0&&Link->HP<Link->MaxHP){
Link->HP += 16;
Game->PlaySound(SFX_HEARTREFILL);
}
if(Link->HP>=Link->MaxHP&&BottleState[BSI_FAIRYTIMER]>=120){
BottleState[BSI_BOTTLETIMER] = 0;
}
}
BottleState[BSI_BOTTLETIMER]--;
NoAction();
if(BottleState[BSI_BOTTLETIMER]<=0){
BottleState[bottle] = BS_EMPTY;
BottleState[BSI_BOTTLEUSED] = -1;
RefreshBottles();
Screen_Unfreeze();
}
}
else{
bottle = UsingEmptyBottle();
if(bottle>-1){
if(BottleState[bottle]==BS_EMPTY){
int scriptname[] = "Bottle_Empty";
int scriptid = Game->GetFFCScript(scriptname);
int Args[8] = {bottle};
RunFFCScript(scriptid, Args);
}
else if(BottleState[bottle]==BS_POTIONRED){
if(Link->HP==Link->MaxHP){
Game->PlaySound(SFX_ERROR);
}
else{
BottleState[BSI_BOTTLEUSED] = bottle;
BottleState[BSI_BOTTLETIMER] = FREQ_HEARTREFILL*REDPOTION_HEARTS;
Screen_Freeze();
}
}
else if(BottleState[bottle]==BS_POTIONGREEN){
if(Link->MP==Link->MaxMP){
Game->PlaySound(SFX_ERROR);
}
else{
BottleState[BSI_BOTTLEUSED] = bottle;
BottleState[BSI_BOTTLETIMER] = GREENPOTION_MP/2;
Screen_Freeze();
}
}
else if(BottleState[bottle]==BS_POTIONBLUE){
if(Link->HP==Link->MaxHP&&Link->MP==Link->MaxMP){
Game->PlaySound(SFX_ERROR);
}
else{
BottleState[BSI_BOTTLEUSED] = bottle;
BottleState[BSI_BOTTLETIMER] = Max(FREQ_HEARTREFILL*BLUEPOTION_HEARTS, BLUEPOTION_MP/2);
BottleState[BSI_OLDHP] = Link->HP;
BottleState[BSI_OLDMP] = Link->MP;
Screen_Freeze();
}
}
else if(BottleState[bottle]==BS_WATER){
Link->Action = LA_ATTACKING;
lweapon l = CreateLWeaponAt(LW_WATER, Link->X+InFrontX(Link->Dir, 0), Link->Y+InFrontY(Link->Dir, 0));
l->UseSprite(SPR_BOTTLEWATER);
l->DeadState = l->ASpeed*l->NumFrames;
l->CollDetection = false;
Game->PlaySound(SFX_BOTTLEWATER);
BottleState[bottle] = BS_EMPTY;
RefreshBottles();
}
else if(BottleState[bottle]==BS_FAIRY){
if(Link->HP==Link->MaxHP){
Game->PlaySound(SFX_ERROR);
}
else{
BottleState[BSI_BOTTLEUSED] = bottle;
BottleState[BSI_BOTTLETIMER] = FREQ_HEARTREFILL*FAIRY_HEARTS;
BottleState[BSI_FAIRYTIMER] = 0;
BottleState[BSI_FAIRYREVIVE] = 0;
Game->PlaySound(SFX_FAIRY);
Screen_Freeze();
}
}
else if(BottleState[bottle]==BS_BEE){
int scriptname[] = "Bottle_Bee";
int scriptid = Game->GetFFCScript(scriptname);
int vars[8] = {1};
RunFFCScript(scriptid, vars);
BottleState[bottle] = BS_EMPTY;
RefreshBottles();
}
}
int fairy = HasFairy();
if(Link->HP<=0&&fairy>-1){
Link->HP = 1;
BottleState[BSI_BOTTLEUSED] = fairy;
BottleState[BSI_BOTTLETIMER] = FREQ_HEARTREFILL*FAIRY_HEARTS;
BottleState[BSI_FAIRYTIMER] = 0;
BottleState[BSI_FAIRYREVIVE] = 1;
Game->PlaySound(SFX_FAIRY);
Screen_Freeze();
}
}
}
//X-------------------------------X
//| Empty Bottle Action Scripts |
//X-------------------------------X
ffc script Bottle_Empty{
void run(int bottleid){
int Angle = 0;
if(Link->Dir==DIR_UP)
Angle = -90;
else if(Link->Dir==DIR_DOWN)
Angle = 90;
else if(Link->Dir==DIR_LEFT)
Angle = 180;
Game->PlaySound(SFX_BOTTLESWING);
Link->Action = LA_ATTACKING;
int Collected = 0;
for(int i=-45; i<45; i+=10){
int X = Link->X+VectorX(12, Angle+i);
int Y = Link->Y+VectorY(12, Angle+i);
Screen->DrawTile(2, X, Y, TIL_BOTTLESWING, 1, 1, CS_BOTTLESWING, -1, -1, X, Y, Angle+i+90, 0, true, 128);
if(Collected==0||Collected==BS_WATER){
if(OnWater(X+8, Y+8)&&Collected==0&&BOTTLE_SETTING_NO_WATER==0){
Collected = BS_WATER;
}
for(int j=1; j<=Screen->NumItems(); j++){
item itm = Screen->LoadItem(j);
if(itm->ID==I_FAIRY||itm->ID==I_FAIRYSTILL){
if(RectCollision(itm->X+itm->HitXOffset, itm->Y+itm->HitYOffset, itm->X+itm->HitXOffset+itm->HitWidth, itm->Y+itm->HitYOffset+itm->HitHeight, X+4, Y+4, X+11, Y+11)){
Collected = BS_FAIRY;
Remove(itm);
break;
}
}
}
for(int j=1; j<=32; j++){
ffc f = Screen->LoadFFC(j);
int scriptname[] = "Bottle_Bee";
int scriptid = Game->GetFFCScript(scriptname);
if(f->Script==scriptid){
if(RectCollision(X+4, Y+4, X+11, Y+11, f->X+4, f->Y+4, f->X+11, f->Y+11)){
Collected = BS_BEE;
f->Misc[FFCM_BEE_SELFDESTRUCT] = 1;
}
}
}
}
WaitNoAction();
}
if(Collected==BS_WATER){
BottleState[bottleid] = BS_WATER;
RefreshBottles();
item itm = CreateItemAt(I_WATERBOTTLE, Link->X, Link->Y);
itm->Pickup = IP_HOLDUP;
}
else if(Collected==BS_FAIRY){
BottleState[bottleid] = BS_FAIRY;
RefreshBottles();
item itm = CreateItemAt(I_FAIRYBOTTLE, Link->X, Link->Y);
itm->Pickup = IP_HOLDUP;
}
else if(Collected==BS_BEE){
BottleState[bottleid] = BS_BEE;
RefreshBottles();
item itm = CreateItemAt(I_BEEBOTTLE, Link->X, Link->Y);
itm->Pickup = IP_HOLDUP;
}
WaitNoAction(10);
}
bool OnWater(int x, int y){
int ct = Screen->ComboT[ComboAt(x, y)];
if(ct==CT_WATER||ct==CT_SHALLOWWATER)
return true;
return false;
}
}
ffc script Bottle_Bee{
void run(int friendly){
this->Data = CMB_BEE;
this->CSet = CS_BEE;
if(friendly==1){
this->X = Link->X;
this->Y = Link->Y;
}
int i; int j; int k;
int X = this->X;
int Y = this->Y;
lweapon lh;
eweapon eh;
int Lifespan = Rand(900, 1200);
for(i=0; i<40; i++){
Y -= 0.5;
this->X = X;
this->Y = Y;
Waitframe();
}
while(Lifespan>0){
int Angle;
if(friendly==1){
int Tx = -1000;
int Ty = -1000;
int Dist = 1000;
for(i=1; i<=Screen->NumNPCs(); i++){
npc n = Screen->LoadNPC(i);
if(Distance(X+8, Y+8, CenterX(n), CenterY(n))<Dist){
Dist = Distance(X+8, Y+8, CenterX(n), CenterY(n));
Tx = CenterX(n)-8;
Ty = CenterY(n)-8;
}
}
Angle = Angle(X, Y, Tx, Ty);
if(Screen->NumNPCs()==0)
Angle = Angle(X, Y, Link->X, Link->Y);
}
else{
if(Distance(Link->X, Link->Y, X, Y)<80&&Rand(2)==0)
Angle = Angle(X, Y, Link->X, Link->Y);
else
Angle = Rand(360);
}
k = Rand(32, 48);
for(i=0; i<k; i++){
Lifespan--;
j = (j+1)%360;
if(j%30==0)
Game->PlaySound(SFX_BEE);
X = Clamp(X+VectorX(2, Angle), -16, 256);
Y = Clamp(Y+VectorY(2, Angle), -16, 176);
this->X = X;
this->Y = Y;
if(friendly==1){
if(lh->isValid()){
lh->X = X;
lh->Y = Y;
}
else{
lh = CreateLWeaponAt(LW_BEE, X, Y);
lh->HitXOffset = 4;
lh->HitYOffset = 4;
lh->HitWidth = 8;
lh->HitHeight = 8;
lh->DrawYOffset = -1000;
lh->Dir = 8;
lh->Damage = DAMAGE_BEE;
}
}
else{
if(eh->isValid()){
eh->X = X;
eh->Y = Y;
}
else{
eh = CreateEWeaponAt(EW_BEE, X, Y);
eh->HitXOffset = 4;
eh->HitYOffset = 4;
eh->HitWidth = 8;
eh->HitHeight = 8;
eh->DrawYOffset = -1000;
eh->Dir = 8;
eh->Damage = DAMAGE_BEE;
}
}
if(this->Misc[FFCM_BEE_SELFDESTRUCT]==1){
if(lh->isValid())
lh->DeadState = 0;
if(eh->isValid())
eh->DeadState = 0;
this->Data = 0;
this->CSet = 0;
Quit();
}
Waitframe();
}
}
if(lh->isValid())
lh->DeadState = 0;
if(eh->isValid())
eh->DeadState = 0;
this->Data = 0;
this->CSet = 0;
for(i=0; i<40; i++){
if(i%2==0)
Screen->FastCombo(2, X, Y, CMB_BEE, CS_BEE, 128);
Waitframe();
}
}
}
//X----------------------------X
//| Other Associated Scripts |
//X----------------------------X
item script PotionFill{
void run(int str, int state){
FillBottle(state);
Screen->Message(str);
}
}
and this
// D0: reserved for other things, like pickup message scripts
// D1: MP cost per frame
// D2: 1 for invincible while cane is in use
// D3: 1 to block enemy projectiles
item script BetterByrnaItem
{
void run(int foo, int cost, int invincible, int block_projectiles)
{
BetterByrna[BETTERBYRNA_COST] = cost;
BetterByrna[BETTERBYRNA_INVINCIBLE] = invincible;
BetterByrna[BETTERBYRNA_BLOCK_PROJECTILES] = block_projectiles;
}
}
const int CUSTOM_LENS_HINTS_MAX_LAYERS = 0; //Maximum layers to check screens for lens hints
//Global script example.
global script LensHints{
void run (){
while (true){
Waitdraw();
DrawCustomLensHints();
Waitframe();
}
}
}
//Main custom lens hint drawing function. Put this into main loop of "Action" global script.
void DrawCustomLensHints(){
if (Link->MP<=0) return;
if (!UsingItem(I_LENS))return;
//Add lens hints here.
DrawCustomLensHint(0, 120, 1028, 8, 1);//Draw combo#1028 with cset 8 on all combos of type 120 (damage 8 hearts)
DrawCustomLensHint(1, 98, 1029, 7, 1);//Draw combo#1029 with cset 7 on all combos with inherent or placed flag 98 (Script 1)
DrawCustomLensHint(2, 55, 1030, 6, 1);//Draw combo#1030 with cset 6 on all NPC`s with ID#55 (Arrow Pols Voices)
//Add more lens hints here.
}
//Lenstype: 0-combo type, 1-combo flag, 2 - NPC.
//miscvalue1: depends on lenstype:
// 0 - combo type ID
// 1 - combo flag ID
// 2 - NPC ID
//cmb - combo to draw, cset - cset to use for hint drawing
//minlevel - minimum item level for Lens-like item needed to be used to reveal this hint.
void DrawCustomLensHint(int lenstype, int miscvalue1, int cmb, int cset, int minlevel){
int lens = GetCurrentItem(IC_LENS);
itemdata it = Game->LoadItemData(lens);
if (it->Level<minlevel) return;
if (lenstype==0){//combo types
for (int l=0; l<=CUSTOM_LENS_HINTS_MAX_LAYERS; l++){
if (l==0){
for (int c=0;c<176;c++){
if (Screen->ComboT[c]==miscvalue1) Screen->FastCombo(0, ComboX(c), ComboY(c), cmb, cset, OP_OPAQUE);
}
if ((Screen->LayerMap(l)==-1)||(Screen->LayerScreen(l)==-1))continue;
for (int c=0;c<176;c++){
int lc = GetLayerComboT(l, c);
if (Screen->ComboT[lc]==miscvalue1) Screen->FastCombo(l, ComboX(lc), ComboY(lc), cmb, cset, OP_OPAQUE);
}
}
}
return;
}
else if (lenstype==1){//combo flags
for (int l=0; l<=CUSTOM_LENS_HINTS_MAX_LAYERS; l++){
if (l==0){
for (int c=0;c<176;c++){
if (ComboFI(c, miscvalue1)) Screen->FastCombo(0, ComboX(c), ComboY(c), cmb, cset, OP_OPAQUE);
}
if ((Screen->LayerMap(l)==-1)||(Screen->LayerScreen(l)==-1))continue;
for (int c=0;c<176;c++){
int lc = GetLayerComboT(l, c);
if (ComboFI(lc, miscvalue1)) Screen->FastCombo(l, ComboX(lc), ComboY(lc), cmb, cset, OP_OPAQUE);
}
}
}
return;
}
else if (lenstype==2){//enemies
for (int i=1; i<= Screen->NumNPCs(); i++ ){
npc lensie= Screen->LoadNPC(i);
if (lensie->ID==miscvalue1) Screen->FastCombo(6, lensie->X, lensie->Y-lensie->Z, cmb, cset, OP_OPAQUE);
}
}
}
//Draws Lens hints on FFC`s if FFC runs given script and has specific value set in checked Init D variable.
void DrawFFCLensHint(int scr, int dreg, int dvalue, int cmb, int cset, int minlevel){
int lens = GetCurrentItem(IC_LENS);
itemdata it = Game->LoadItemData(lens);
if (it->Level<minlevel) return;
for (int i=1;i<=32;i++){
ffc lensie = Screen->LoadFFC(i);
if (lensie->Script!=scr) continue;
if (lensie->InitD[dreg]!=dvalue) continue;
Screen->FastCombo(0, CenterX(lensie), CenterY(lensie), cmb, cset, OP_OPAQUE);
}
}
//FFC version of custom lens hints.
//D0 - Lenstype: 0-combo type, 1-combo flag, 2 - NPC.
//D1: depends on lenstype:
// 0 - combo type ID
// 1 - combo flag ID
// 2 - NPC ID
//D2 - combo to draw,
//D3 - cset to use for hint drawing
//D4 - minimum item level for Lens-like item needed to be used to reveal this hint.
ffc script CustomLensHints{
void run (int lenstype, int miscvalue1, int cmb, int cset, int minlevel){
while (true){
DrawCustomLensHint(lenstype, miscvalue1, cmb, cset, minlevel);
Waitframe();
}
}
}
//X--------------------X
//| Bottle Constants |
//X--------------------X
const int FFC_SFA = 31; //FFC used for screen freeze A
const int FFC_SFB = 32; //FFC used for screen freeze B
const int CMB_SFA = 2; //Combo used for screen freeze A
const int CMB_SFB = 3; //Combo used for screen freeze B
const int BOTTLE_SETTING_NO_WATER = 0; //Set to 1 if water shouldn't be bottleable
const int TIL_BOTTLE = 52020; //First of the tiles used for the bottle items. Should come in four identical rows.
//Tile order in each row should go as such:
//Empty, Empty, Red Potion, Green Potion, Blue Potion, Water, Fairy, Bee
const int REDPOTION_HEARTS = 8; //Hearts the red potion heals
const int GREENPOTION_MP = 256; //MP the green potion restores
const int BLUEPOTION_HEARTS = 16; //Hearts the blue potion heals
const int BLUEPOTION_MP = 256; //MP the blue potion restores
const int LW_WATER = 31; //LWeapon type used for bottled water. Script 1 by default
const int SPR_BOTTLEWATER = 88; //Sprite used for bottled water
const int SFX_BOTTLEWATER = 55; //Sound when water is dumped out
const int FAIRY_HEARTS = 3; //Hearts healed by a fairy
const int CMB_FAIRY = 904; //Fairy combo
const int CS_FAIRY = 8; //Fairy cset
const int SFX_FAIRY = 64; //Sound that plays when a fairy appears
const int IC_BOTTLE = 67; //Item class used for bottles. Custom 1 by default.
const int I_BOTTLE1 = 143; //Item ID for the first bottle (Level 1)
const int I_BOTTLE2 = 144; //Item ID for the second bottle (Level 2)
const int I_BOTTLE3 = 145; //Item ID for the second bottle (Level 3)
const int I_BOTTLE4 = 146; //Item ID for the second bottle (Level 4)
const int FREQ_HEARTREFILL = 8; //Frequency in frames at which potions/fairies restore hearts
const int SFX_HEARTREFILL = 22; //Sound when potion/fairy restores a heart
const int FREQ_MAGICSOUND = 8; //Frequency in frames where the magic refill sound plays
const int SFX_MAGICREFILL = 61; //Magic refill sound
const int SFX_ERROR = 62; //Error sound
const int TIL_BOTTLESWING = 52006; //Tile of a right facing open bottle used when trying to catch something
const int CS_BOTTLESWING = 11; //CSet of the swinging bottle
const int SFX_BOTTLESWING = 63; //Sound used for the bottle being swung
const int I_WATERBOTTLE = 150; //Item for bottle water pickup
const int I_FAIRYBOTTLE = 151; //Item for bottle fairy pickup
const int I_BEEBOTTLE = 152; //Item for bottle bee pickup
const int CMB_BEE = 905; //Combo used for the bee
const int CS_BEE = 8; //CSet used for the bee
const int SFX_BEE = 65; //SFX used for the bee
const int LW_BEE = 32; //Lweapon used for the bee (Script 2 by default)
const int EW_BEE = 32; //Eweapon used for the bee (Script 2 by default)
const int DAMAGE_BEE = 4; //Damage the bee deals
const int FFCM_BEE_SELFDESTRUCT = 0; //FFC misc used to tell the bee to disappear
const int STR_CANTAFFORD = 2; //Message for when you can't afford an item
const int STR_NOBOTTLE = 3; //Message for when you don't have a bottle to store a potion in
const int C_WHITE = 0x01; //The color white
const int C_BLACK = 0x0F; //The color black
//X--------------------------X
//| Screen Freeze Function |
//X--------------------------X
void Screen_Freeze(){
ffc f1 = Screen->LoadFFC(FFC_SFA);
ffc f2 = Screen->LoadFFC(FFC_SFB);
f1->Data = CMB_SFA;
f2->Data = CMB_SFB;
}
void Screen_Unfreeze(){
ffc f1 = Screen->LoadFFC(FFC_SFA);
ffc f2 = Screen->LoadFFC(FFC_SFB);
f1->Data = 0;
f2->Data = 0;
}
//X--------------------------X
//| Empty Bottle Functions |
//X--------------------------X
//X--------------------------------------------------------X
//| These constants don't need to be changed. |
//| They just define various states of the empty bottle. |
//| BS_ constants are also used for the potion filling |
//| pickup item script. Look here to see what to set D2 |
//| to for that. |
//X--------------------------------------------------------X
// |
const int BS_EMPTY = 0; // |
const int BS_POTIONRED = 1; // |
const int BS_POTIONGREEN = 2; // |
const int BS_POTIONBLUE = 3; // |
const int BS_WATER = 4; // |
const int BS_FAIRY = 5; // |
const int BS_BEE = 6; // |
// |
const int BSI_BOTTLEUSED = 4; // |
const int BSI_BOTTLETIMER = 5; // |
const int BSI_OLDHP = 6; // |
const int BSI_OLDMP = 7; // |
const int BSI_FAIRYTIMER = 8; // |
const int BSI_FAIRYREVIVE = 9; // |
// |
//---------------------------------------------------------X
int BottleState[12]; //0-3: States of bottles, 4: Bottle used,
//5: Potion timer, 6: OldHP, 7: OldMP
//This function should be called at the beginning of your global and
//refreshes the graphics for the bottles.
void RefreshBottles(){
for(int i=0; i<4; i++){
CopyTile(TIL_BOTTLE+20*i+1+BottleState[i], TIL_BOTTLE+20*i);
}
}
int UsingEmptyBottle(){
if(Link->PressA){
int id = GetEquipmentA();
if(id>0){
itemdata A = Game->LoadItemData(id);
if(A->Family==IC_BOTTLE)
return A->Level-1;
}
}
else if(Link->PressB){
int id = GetEquipmentB();
if(id>0){
itemdata B = Game->LoadItemData(id);
if(B->Family==IC_BOTTLE)
return B->Level-1;
}
}
return -1;
}
bool CanFillBottle(){
int bottles[4] = {I_BOTTLE1, I_BOTTLE2, I_BOTTLE3, I_BOTTLE4};
for(int i=0; i<4; i++){
if(Link->Item[bottles[i]]&&BottleState[i]==BS_EMPTY)
return true;
}
return false;
}
int FillBottle(int state){
int bottles[4] = {I_BOTTLE1, I_BOTTLE2, I_BOTTLE3, I_BOTTLE4};
for(int i=0; i<4; i++){
if(Link->Item[bottles[i]]&&BottleState[i]==BS_EMPTY){
BottleState[i] = state;
RefreshBottles();
return i;
}
}
}
int HasFairy(){
int bottles[4] = {I_BOTTLE1, I_BOTTLE2, I_BOTTLE3, I_BOTTLE4};
for(int i=0; i<4; i++){
if(Link->Item[bottles[i]]&&BottleState[i]==BS_FAIRY)
return i;
}
return -1;
}
//This function goes in the while loop of your global script before waitdraw
void EmptyBottleGlobal(){
int bottle = BottleState[BSI_BOTTLEUSED];
if(BottleState[BSI_BOTTLETIMER]>0){
if(BottleState[bottle]==BS_POTIONRED){
if(BottleState[BSI_BOTTLETIMER]%FREQ_HEARTREFILL==0){
Link->HP += 16;
Game->PlaySound(SFX_HEARTREFILL);
if(Link->HP>=Link->MaxHP){
BottleState[BSI_BOTTLETIMER] = 0;
}
}
}
else if(BottleState[bottle]==BS_POTIONGREEN){
Link->MP += 2;
if(BottleState[BSI_BOTTLETIMER]%FREQ_MAGICSOUND==0)
Game->PlaySound(SFX_MAGICREFILL);
if(Link->MP>=Link->MaxMP){
BottleState[BSI_BOTTLETIMER] = 0;
}
}
else if(BottleState[bottle]==BS_POTIONBLUE){
if(BottleState[BSI_BOTTLETIMER]%FREQ_HEARTREFILL==0&&Link->HP<BottleState[BSI_OLDHP]+BLUEPOTION_HEARTS*16&&Link->HP<Link->MaxHP){
Link->HP += 16;
Game->PlaySound(SFX_HEARTREFILL);
}
if(Link->MP<BottleState[BSI_OLDMP]+BLUEPOTION_MP&&Link->MP<Link->MaxMP){
if(BottleState[BSI_BOTTLETIMER]%FREQ_MAGICSOUND==0)
Game->PlaySound(SFX_MAGICREFILL);
Link->MP += 2;
}
if(Link->HP>=Link->MaxHP&&Link->MP>=Link->MaxMP){
BottleState[BSI_BOTTLETIMER] = 0;
}
}
else if(BottleState[bottle]==BS_FAIRY){
if(BottleState[BSI_BOTTLETIMER]<2&&BottleState[BSI_FAIRYTIMER]<120)
BottleState[BSI_BOTTLETIMER] = 2;
BottleState[BSI_FAIRYTIMER]++;
int X = Link->X+VectorX(16*(BottleState[BSI_FAIRYTIMER]/120), BottleState[BSI_FAIRYTIMER]*8);
int Y = Link->Y+VectorY(8*(BottleState[BSI_FAIRYTIMER]/120), BottleState[BSI_FAIRYTIMER]*8)-BottleState[BSI_FAIRYTIMER]/8;
if(BottleState[BSI_FAIRYREVIVE]==1){
if(BottleState[BSI_FAIRYTIMER]<10||BottleState[BSI_FAIRYTIMER]>110)
Screen->Rectangle(6, 0, 0, 256, 176, C_BLACK, 1, 0, 0, 0, true, 64);
else
Screen->Rectangle(6, 0, 0, 256, 176, C_BLACK, 1, 0, 0, 0, true, 128);
Screen->FastTile(6, Link->X+Link->DrawXOffset, Link->Y+Link->DrawYOffset, Link->Tile, 6, 128);
}
if(BottleState[BSI_FAIRYTIMER]<80||BottleState[BSI_FAIRYTIMER]%2==0)
Screen->FastCombo(6, X, Y, CMB_FAIRY, CS_FAIRY, 128);
if(BottleState[BSI_BOTTLETIMER]%FREQ_HEARTREFILL==0&&Link->HP<Link->MaxHP){
Link->HP += 16;
Game->PlaySound(SFX_HEARTREFILL);
}
if(Link->HP>=Link->MaxHP&&BottleState[BSI_FAIRYTIMER]>=120){
BottleState[BSI_BOTTLETIMER] = 0;
}
}
BottleState[BSI_BOTTLETIMER]--;
NoAction();
if(BottleState[BSI_BOTTLETIMER]<=0){
BottleState[bottle] = BS_EMPTY;
BottleState[BSI_BOTTLEUSED] = -1;
RefreshBottles();
Screen_Unfreeze();
}
}
else{
bottle = UsingEmptyBottle();
if(bottle>-1){
if(BottleState[bottle]==BS_EMPTY){
int scriptname[] = "Bottle_Empty";
int scriptid = Game->GetFFCScript(scriptname);
int Args[8] = {bottle};
RunFFCScript(scriptid, Args);
}
else if(BottleState[bottle]==BS_POTIONRED){
if(Link->HP==Link->MaxHP){
Game->PlaySound(SFX_ERROR);
}
else{
BottleState[BSI_BOTTLEUSED] = bottle;
BottleState[BSI_BOTTLETIMER] = FREQ_HEARTREFILL*REDPOTION_HEARTS;
Screen_Freeze();
}
}
else if(BottleState[bottle]==BS_POTIONGREEN){
if(Link->MP==Link->MaxMP){
Game->PlaySound(SFX_ERROR);
}
else{
BottleState[BSI_BOTTLEUSED] = bottle;
BottleState[BSI_BOTTLETIMER] = GREENPOTION_MP/2;
Screen_Freeze();
}
}
else if(BottleState[bottle]==BS_POTIONBLUE){
if(Link->HP==Link->MaxHP&&Link->MP==Link->MaxMP){
Game->PlaySound(SFX_ERROR);
}
else{
BottleState[BSI_BOTTLEUSED] = bottle;
BottleState[BSI_BOTTLETIMER] = Max(FREQ_HEARTREFILL*BLUEPOTION_HEARTS, BLUEPOTION_MP/2);
BottleState[BSI_OLDHP] = Link->HP;
BottleState[BSI_OLDMP] = Link->MP;
Screen_Freeze();
}
}
else if(BottleState[bottle]==BS_WATER){
Link->Action = LA_ATTACKING;
lweapon l = CreateLWeaponAt(LW_WATER, Link->X+InFrontX(Link->Dir, 0), Link->Y+InFrontY(Link->Dir, 0));
l->UseSprite(SPR_BOTTLEWATER);
l->DeadState = l->ASpeed*l->NumFrames;
l->CollDetection = false;
Game->PlaySound(SFX_BOTTLEWATER);
BottleState[bottle] = BS_EMPTY;
RefreshBottles();
}
else if(BottleState[bottle]==BS_FAIRY){
if(Link->HP==Link->MaxHP){
Game->PlaySound(SFX_ERROR);
}
else{
BottleState[BSI_BOTTLEUSED] = bottle;
BottleState[BSI_BOTTLETIMER] = FREQ_HEARTREFILL*FAIRY_HEARTS;
BottleState[BSI_FAIRYTIMER] = 0;
BottleState[BSI_FAIRYREVIVE] = 0;
Game->PlaySound(SFX_FAIRY);
Screen_Freeze();
}
}
else if(BottleState[bottle]==BS_BEE){
int scriptname[] = "Bottle_Bee";
int scriptid = Game->GetFFCScript(scriptname);
int vars[8] = {1};
RunFFCScript(scriptid, vars);
BottleState[bottle] = BS_EMPTY;
RefreshBottles();
}
}
int fairy = HasFairy();
if(Link->HP<=0&&fairy>-1){
Link->HP = 1;
BottleState[BSI_BOTTLEUSED] = fairy;
BottleState[BSI_BOTTLETIMER] = FREQ_HEARTREFILL*FAIRY_HEARTS;
BottleState[BSI_FAIRYTIMER] = 0;
BottleState[BSI_FAIRYREVIVE] = 1;
Game->PlaySound(SFX_FAIRY);
Screen_Freeze();
}
}
}
//X-------------------------------X
//| Empty Bottle Action Scripts |
//X-------------------------------X
ffc script Bottle_Empty{
void run(int bottleid){
int Angle = 0;
if(Link->Dir==DIR_UP)
Angle = -90;
else if(Link->Dir==DIR_DOWN)
Angle = 90;
else if(Link->Dir==DIR_LEFT)
Angle = 180;
Game->PlaySound(SFX_BOTTLESWING);
Link->Action = LA_ATTACKING;
int Collected = 0;
for(int i=-45; i<45; i+=10){
int X = Link->X+VectorX(12, Angle+i);
int Y = Link->Y+VectorY(12, Angle+i);
Screen->DrawTile(2, X, Y, TIL_BOTTLESWING, 1, 1, CS_BOTTLESWING, -1, -1, X, Y, Angle+i+90, 0, true, 128);
if(Collected==0||Collected==BS_WATER){
if(OnWater(X+8, Y+8)&&Collected==0&&BOTTLE_SETTING_NO_WATER==0){
Collected = BS_WATER;
}
for(int j=1; j<=Screen->NumItems(); j++){
item itm = Screen->LoadItem(j);
if(itm->ID==I_FAIRY||itm->ID==I_FAIRYSTILL){
if(RectCollision(itm->X+itm->HitXOffset, itm->Y+itm->HitYOffset, itm->X+itm->HitXOffset+itm->HitWidth, itm->Y+itm->HitYOffset+itm->HitHeight, X+4, Y+4, X+11, Y+11)){
Collected = BS_FAIRY;
Remove(itm);
break;
}
}
}
for(int j=1; j<=32; j++){
ffc f = Screen->LoadFFC(j);
int scriptname[] = "Bottle_Bee";
int scriptid = Game->GetFFCScript(scriptname);
if(f->Script==scriptid){
if(RectCollision(X+4, Y+4, X+11, Y+11, f->X+4, f->Y+4, f->X+11, f->Y+11)){
Collected = BS_BEE;
f->Misc[FFCM_BEE_SELFDESTRUCT] = 1;
}
}
}
}
WaitNoAction();
}
if(Collected==BS_WATER){
BottleState[bottleid] = BS_WATER;
RefreshBottles();
item itm = CreateItemAt(I_WATERBOTTLE, Link->X, Link->Y);
itm->Pickup = IP_HOLDUP;
}
else if(Collected==BS_FAIRY){
BottleState[bottleid] = BS_FAIRY;
RefreshBottles();
item itm = CreateItemAt(I_FAIRYBOTTLE, Link->X, Link->Y);
itm->Pickup = IP_HOLDUP;
}
else if(Collected==BS_BEE){
BottleState[bottleid] = BS_BEE;
RefreshBottles();
item itm = CreateItemAt(I_BEEBOTTLE, Link->X, Link->Y);
itm->Pickup = IP_HOLDUP;
}
WaitNoAction(10);
}
bool OnWater(int x, int y){
int ct = Screen->ComboT[ComboAt(x, y)];
if(ct==CT_WATER||ct==CT_SHALLOWWATER)
return true;
return false;
}
}
ffc script Bottle_Bee{
void run(int friendly){
this->Data = CMB_BEE;
this->CSet = CS_BEE;
if(friendly==1){
this->X = Link->X;
this->Y = Link->Y;
}
int i; int j; int k;
int X = this->X;
int Y = this->Y;
lweapon lh;
eweapon eh;
int Lifespan = Rand(900, 1200);
for(i=0; i<40; i++){
Y -= 0.5;
this->X = X;
this->Y = Y;
Waitframe();
}
while(Lifespan>0){
int Angle;
if(friendly==1){
int Tx = -1000;
int Ty = -1000;
int Dist = 1000;
for(i=1; i<=Screen->NumNPCs(); i++){
npc n = Screen->LoadNPC(i);
if(Distance(X+8, Y+8, CenterX(n), CenterY(n))<Dist){
Dist = Distance(X+8, Y+8, CenterX(n), CenterY(n));
Tx = CenterX(n)-8;
Ty = CenterY(n)-8;
}
}
Angle = Angle(X, Y, Tx, Ty);
if(Screen->NumNPCs()==0)
Angle = Angle(X, Y, Link->X, Link->Y);
}
else{
if(Distance(Link->X, Link->Y, X, Y)<80&&Rand(2)==0)
Angle = Angle(X, Y, Link->X, Link->Y);
else
Angle = Rand(360);
}
k = Rand(32, 48);
for(i=0; i<k; i++){
Lifespan--;
j = (j+1)%360;
if(j%30==0)
Game->PlaySound(SFX_BEE);
X = Clamp(X+VectorX(2, Angle), -16, 256);
Y = Clamp(Y+VectorY(2, Angle), -16, 176);
this->X = X;
this->Y = Y;
if(friendly==1){
if(lh->isValid()){
lh->X = X;
lh->Y = Y;
}
else{
lh = CreateLWeaponAt(LW_BEE, X, Y);
lh->HitXOffset = 4;
lh->HitYOffset = 4;
lh->HitWidth = 8;
lh->HitHeight = 8;
lh->DrawYOffset = -1000;
lh->Dir = 8;
lh->Damage = DAMAGE_BEE;
}
}
else{
if(eh->isValid()){
eh->X = X;
eh->Y = Y;
}
else{
eh = CreateEWeaponAt(EW_BEE, X, Y);
eh->HitXOffset = 4;
eh->HitYOffset = 4;
eh->HitWidth = 8;
eh->HitHeight = 8;
eh->DrawYOffset = -1000;
eh->Dir = 8;
eh->Damage = DAMAGE_BEE;
}
}
if(this->Misc[FFCM_BEE_SELFDESTRUCT]==1){
if(lh->isValid())
lh->DeadState = 0;
if(eh->isValid())
eh->DeadState = 0;
this->Data = 0;
this->CSet = 0;
Quit();
}
Waitframe();
}
// D0: reserved for other things, like pickup message scripts
// D1: MP cost per frame
// D2: 1 for invincible while cane is in use
// D3: 1 to block enemy projectiles
item script BetterByrnaItem
{
void run(int foo, int cost, int invincible, int block_projectiles)
{
BetterByrna[BETTERBYRNA_COST] = cost;
BetterByrna[BETTERBYRNA_INVINCIBLE] = invincible;
BetterByrna[BETTERBYRNA_BLOCK_PROJECTILES] = block_projectiles;
}
}
const int CUSTOM_LENS_HINTS_MAX_LAYERS = 0; //Maximum layers to check screens for lens hints
//Global script example.
global script LensHints{
void run (){
while (true){
Waitdraw();
DrawCustomLensHints();
Waitframe();
}
}
}
//Main custom lens hint drawing function. Put this into main loop of "Action" global script.
void DrawCustomLensHints(){
if (Link->MP<=0) return;
if (!UsingItem(I_LENS))return;
//Add lens hints here.
DrawCustomLensHint(0, 120, 1028, 8, 1);//Draw combo#1028 with cset 8 on all combos of type 120 (damage 8 hearts)
DrawCustomLensHint(1, 98, 1029, 7, 1);//Draw combo#1029 with cset 7 on all combos with inherent or placed flag 98 (Script 1)
DrawCustomLensHint(2, 55, 1030, 6, 1);//Draw combo#1030 with cset 6 on all NPC`s with ID#55 (Arrow Pols Voices)
//Add more lens hints here.
}
//Lenstype: 0-combo type, 1-combo flag, 2 - NPC.
//miscvalue1: depends on lenstype:
// 0 - combo type ID
// 1 - combo flag ID
// 2 - NPC ID
//cmb - combo to draw, cset - cset to use for hint drawing
//minlevel - minimum item level for Lens-like item needed to be used to reveal this hint.
void DrawCustomLensHint(int lenstype, int miscvalue1, int cmb, int cset, int minlevel){
int lens = GetCurrentItem(IC_LENS);
itemdata it = Game->LoadItemData(lens);
if (it->Level<minlevel) return;
if (lenstype==0){//combo types
for (int l=0; l<=CUSTOM_LENS_HINTS_MAX_LAYERS; l++){
if (l==0){
for (int c=0;c<176;c++){
if (Screen->ComboT[c]==miscvalue1) Screen->FastCombo(0, ComboX(c), ComboY(c), cmb, cset, OP_OPAQUE);
}
if ((Screen->LayerMap(l)==-1)||(Screen->LayerScreen(l)==-1))continue;
for (int c=0;c<176;c++){
int lc = GetLayerComboT(l, c);
if (Screen->ComboT[lc]==miscvalue1) Screen->FastCombo(l, ComboX(lc), ComboY(lc), cmb, cset, OP_OPAQUE);
}
}
}
return;
}
else if (lenstype==1){//combo flags
for (int l=0; l<=CUSTOM_LENS_HINTS_MAX_LAYERS; l++){
if (l==0){
for (int c=0;c<176;c++){
if (ComboFI(c, miscvalue1)) Screen->FastCombo(0, ComboX(c), ComboY(c), cmb, cset, OP_OPAQUE);
}
if ((Screen->LayerMap(l)==-1)||(Screen->LayerScreen(l)==-1))continue;
for (int c=0;c<176;c++){
int lc = GetLayerComboT(l, c);
if (ComboFI(lc, miscvalue1)) Screen->FastCombo(l, ComboX(lc), ComboY(lc), cmb, cset, OP_OPAQUE);
}
}
}
return;
}
else if (lenstype==2){//enemies
for (int i=1; i<= Screen->NumNPCs(); i++ ){
npc lensie= Screen->LoadNPC(i);
if (lensie->ID==miscvalue1) Screen->FastCombo(6, lensie->X, lensie->Y-lensie->Z, cmb, cset, OP_OPAQUE);
}
}
}
//Draws Lens hints on FFC`s if FFC runs given script and has specific value set in checked Init D variable.
void DrawFFCLensHint(int scr, int dreg, int dvalue, int cmb, int cset, int minlevel){
int lens = GetCurrentItem(IC_LENS);
itemdata it = Game->LoadItemData(lens);
if (it->Level<minlevel) return;
for (int i=1;i<=32;i++){
ffc lensie = Screen->LoadFFC(i);
if (lensie->Script!=scr) continue;
if (lensie->InitD[dreg]!=dvalue) continue;
Screen->FastCombo(0, CenterX(lensie), CenterY(lensie), cmb, cset, OP_OPAQUE);
}
}
//FFC version of custom lens hints.
//D0 - Lenstype: 0-combo type, 1-combo flag, 2 - NPC.
//D1: depends on lenstype:
// 0 - combo type ID
// 1 - combo flag ID
// 2 - NPC ID
//D2 - combo to draw,
//D3 - cset to use for hint drawing
//D4 - minimum item level for Lens-like item needed to be used to reveal this hint.
ffc script CustomLensHints{
void run (int lenstype, int miscvalue1, int cmb, int cset, int minlevel){
while (true){
DrawCustomLensHint(lenstype, miscvalue1, cmb, cset, minlevel);
Waitframe();
}
}
}
//X--------------------X
//| Bottle Constants |
//X--------------------X
const int FFC_SFA = 31; //FFC used for screen freeze A
const int FFC_SFB = 32; //FFC used for screen freeze B
const int CMB_SFA = 2; //Combo used for screen freeze A
const int CMB_SFB = 3; //Combo used for screen freeze B
const int BOTTLE_SETTING_NO_WATER = 0; //Set to 1 if water shouldn't be bottleable
overall this script file is real long and i think i am repeating lines so I'll just leave it at that
it's just 5000 lines of code