Copy to Clipboard Test

Lift and Place Combos Code

const int SFX_PICKPLACE_PICK = 4;//Sound to play,when liftable combo is picked.
const int SFX_PICKPLACE_PLACE = 16;//Sound to play,when liftable combo is placed.

const int CT_PICKPLACE_LIFTABLE = 142;//Combo that is defined as liftable

const int PICKPLACE_LIFT_OFFSET = 8;//Y offset for rendering lifted combos

const int LINK_MISC_COMBO_IN_HAND = 1;//Index to Link`s misc var for ID of carried combo
const int LINK_MISC_CSET_IN_HAND = 2;//Index to Link`s misc var for cset of carried combo
//Pick and place combos, like Minecraft. 
//Place anywhere in the screen. 
//D0 - bracelet power requirement. 
//D1 - >0 - allow tile swapping
ffc script PickPlaceCombos{
	void run (int weight, int allowswap){
		Link->Misc[LINK_MISC_COMBO_IN_HAND]=0;
		Link->Misc[LINK_MISC_CSET_IN_HAND]=0;
		int cmb = -1;
		int bufferd = 0;
		int bufferc = 0;
		int buffert = 0;
		while(true){
			cmb = ComboAt(CenterLinkX(), CenterLinkY());
			if (Link->PressEx1){
				if (Link->Misc[LINK_MISC_COMBO_IN_HAND]==0){ 
					if (!ComboFI(cmb, CF_NOBLOCKS)  &&  CanLift(weight) && Screen->ComboT[cmb]==CT_PICKPLACE_LIFTABLE){
						Game->PlaySound(SFX_PICKPLACE_PICK);
						Link->Misc[LINK_MISC_COMBO_IN_HAND]=Screen->ComboD[cmb];
						Link->Misc[LINK_MISC_CSET_IN_HAND] = Screen->ComboC[cmb];
						Screen->ComboD[cmb]=Screen->UnderCombo;
						Screen->ComboC[cmb]=Screen->UnderCSet;
					}
				}
				else if (!ComboFI(cmb, CF_NOBLOCKS) && (Screen->ComboT[cmb]!=CT_PICKPLACE_LIFTABLE || allowswap>0) && Link->Misc[LINK_MISC_COMBO_IN_HAND]>0){
					bufferd = Screen->ComboD[cmb];
					bufferc = Screen->ComboC[cmb];
					buffert = Screen->ComboT[cmb];
					Game->PlaySound(SFX_PICKPLACE_PLACE);
					Screen->ComboD[cmb]=Link->Misc[LINK_MISC_COMBO_IN_HAND];
					Screen->ComboC[cmb]=Link->Misc[LINK_MISC_CSET_IN_HAND];
					Link->Misc[LINK_MISC_COMBO_IN_HAND]=0;
					Link->Misc[LINK_MISC_CSET_IN_HAND]=0;
					if (allowswap>0 && buffert==CT_PICKPLACE_LIFTABLE){
						Game->PlaySound(SFX_PICKPLACE_PICK);
						Link->Misc[LINK_MISC_COMBO_IN_HAND]=bufferd;
						Link->Misc[LINK_MISC_CSET_IN_HAND] = bufferc;
					}
				}
			}
			if (Link->Misc[LINK_MISC_COMBO_IN_HAND]>0)Screen->FastCombo(4, Link->X, Link->Y-PICKPLACE_LIFT_OFFSET, Link->Misc[LINK_MISC_COMBO_IN_HAND], Link->Misc[LINK_MISC_CSET_IN_HAND], OP_OPAQUE);
			Waitframe();
		}
	}
}

// Returns Link`s pushing power
bool CanLift(int weight){
	int result = -1;
	int highestlevel = -1;
	int power =0;
	for(int i=0; i<=MAX_HIGHEST_LEVEL_ITEM_CHECK; ++i)	{
		itemdata id = Game->LoadItemData(i);
		if(id->Family == IC_BRACELET && Link->Item[i]){
			if(id->Level >= highestlevel){
				highestlevel = id->Level;
				result=i;
			}
		}
	}
	if (result<0)return weight<=0;
	itemdata it = Game->LoadItemData(result);
	return (it->Power) >=weight;
}

//const int LAYER_STACK_DROP = 4;

//Stackable pick/place comb pillsr.
//Place FFC with solid combo at base
//D0 - bracelet level requirement.
//D1 - number of combos in column at start.
//D2 - maximum number of elements in pillar
ffc script StackDropLift{
	void run (int weight, int initcount, int cap){
		int cmb = ComboAt(CenterX(this), CenterY(this));
		int numcmb=initcount;
		int curpos = cmb-16*initcount-16;
		while(true){			
			if (Link->PressEx1 && Link->Y == this->Y + 8 && (Link->X < this->X + 8 && Link->X > this->X - 8) && Link->Dir == DIR_UP){
				if (Link->Misc[LINK_MISC_COMBO_IN_HAND]==0){
					if (numcmb>0 && CanLift(weight)){	
						Game->PlaySound(SFX_PICKPLACE_PICK);
						Link->Misc[LINK_MISC_COMBO_IN_HAND]=Screen->ComboD[curpos+16];
						Link->Misc[LINK_MISC_CSET_IN_HAND]=Screen->ComboC[curpos+16];
						Screen->ComboD[curpos+16] = Screen->UnderCombo;
						Screen->ComboC[curpos+16] =Screen->UnderCSet;
						curpos+=16;
						numcmb--;
					}
				}
				else{
					if (numcmb<cap){
						Game->PlaySound(SFX_PICKPLACE_PLACE);
						Screen->ComboD[curpos] = Link->Misc[LINK_MISC_COMBO_IN_HAND];
						Screen->ComboC[curpos] = Link->Misc[LINK_MISC_CSET_IN_HAND];
						Link->Misc[LINK_MISC_COMBO_IN_HAND]=0;
						Link->Misc[LINK_MISC_CSET_IN_HAND]=0;
						curpos-=16;
						numcmb++;
					}
				}
			}
			Waitframe();
		}
	}
}		

const int  SFX_TIMEDROP_SUCCESS = 27;//Sound to play on succeful filling of the hole
const int  SFX_TIMEDROP_FAIL = 32;//Sound to play on incorrect combo drop
const int  SFX_TIMEDROP_FAIL2 = 38;//Sound to play on mistimed combo drop

//Timed colored hole.
//Animated hole that must be filled by dropping correct combo within specific timing to solve the puzzle.

//Effect width and height used
//Set up sequence of combos for animation
//D0 - ID of correct combo to drop
//D1 - CSet of correct combo to drop
//D2 - delay between frame changing in animation, in frames.
//D3 - D2 - target animation frame for timed combo drop, starting from 0. -1 = no timing needed.
//D4 - number of frames in animation
ffc script TimedColorDropper{
	void run (int cdrop, int csdrop, int cyclespeed, int frame, int numframes){
		int timer=0;
		int origdata = this->Data;
		int curframe=0;
		bool wild = (frame<0);
		while(true){
			if (this->InitD[7] == 0){
				timer++;
				if (timer>=cyclespeed){
					curframe++;
					timer=0;
				}
				if (curframe>=numframes)curframe=0;
				if (wild) frame=curframe;
			}
			if (Link->PressEx1 && RectCollision(Link->X+7, Link->Y+7, Link->X+8, Link->Y+8, this->X, this->Y, this->X+this->EffectWidth-1, this->Y+this->EffectHeight-1)){
				if (Link->Misc[LINK_MISC_COMBO_IN_HAND]>0 && this->InitD[7]==0){
					if (curframe==frame && Link->Misc[LINK_MISC_COMBO_IN_HAND]==cdrop && Link->Misc[LINK_MISC_CSET_IN_HAND]==csdrop){
						Game->PlaySound(SFX_TIMEDROP_SUCCESS);
						this->InitD[7]=1;
						for(int i=1;i<=33;i++){
							if (Screen->State[ST_SECRET]) break;
							if (i==33){
								Game->PlaySound(SFX_SECRET);
								Screen->TriggerSecrets();
								Screen->State[ST_SECRET]=true;
								break;
							}
							ffc n = Screen->LoadFFC(i);
							if (n->Script!=this->Script)continue;
							if (n->InitD[7] == 0) break;
						}
					}
					else{
						if (curframe!=frame) Game->PlaySound(SFX_TIMEDROP_FAIL2);
						if(Link->Misc[LINK_MISC_COMBO_IN_HAND]!=cdrop || Link->Misc[LINK_MISC_CSET_IN_HAND]!=csdrop) Game->PlaySound(SFX_TIMEDROP_FAIL);
					}
					Link->Misc[LINK_MISC_COMBO_IN_HAND]=0;
					Link->Misc[LINK_MISC_CSET_IN_HAND]=0;
				}
			}
			this->Data=origdata+curframe;
			if (this->InitD[7]==1)Screen->FastCombo(2, CenterX(this)-8, CenterY(this)-8, cdrop, csdrop, OP_OPAQUE);
			//if (curframe==frame)Screen->Rectangle(3, this->X, this->Y, this->X+47, this->Y+47, 1, -1, 0, 0, 0, false, OP_OPAQUE);
			Waitframe();
		}		
	}
}