Hello. Another fail of mine at combining global scripts was done. This is just because the global scripts contain more than just the stuff between while(true) and Waitframe().
For example a void run thing above the main loop or some more while(true) and Waitframe() things.
The tutorial of combining global scripts doesn't help me at all, even when I read it carefully.
So that's why I need you of combining Mero's Solid FFC script with my actual global one. Do you think you can do it?
Mero's Solid FFC Script
//import "std.zh" //Global Constants const int MISC_SOLIDFFC = 14; //A misc value between 0 and 15 to denote a ffc as solid. const int MISC_SFFC_X = 0; //This can be used by other ffcs as long as they're not solid. const int SFFC_SIDEVIEWTHRESHOLD = 12; //Sideview X Overlap: used for hitdetection. const int CRUSH_DAMAGE = 8; //Damage in 16ths of a heart dealt to link when he is crushed. const int SF_SIDEWARP = 2; //The flag to denote that Left/Right sidewarps are used on a screen. const int BIG_LINK = 0; const int CT_LADDER = 0; //If not using CT_RIGHTSTATUE //Don't touch me, don't even think about setting these variables. HEY! float SFFC_LinkX; float SFFC_LinkY; // this utility routine by Saffith checks for walkability of combos bool isSolid(int x, int y){ if(x<0 || x>255 || y<0 || y>175) return false; int mask=1111b; if(x%16< 8) mask&=0011b; else mask&=1100b; if(y%16< 8) mask&=0101b; else mask&=1010b; return (!(Screen->ComboS[ComboAt(x, y)]&mask)==0); } // this utility is used by the ffcs to check if the platform can move link. bool CanMoveLink(int x){ if(x > 0) x+=Link->X+16; else if(x < 0) x+=Link->X-1; if(x<0) return (Game->GetCurScreen()%16==0 && ScreenFlag(SF_MISC, SF_SIDEWARP)); if(x>240) return (Game->GetCurScreen()%16==15 && ScreenFlag(SF_MISC,SF_SIDEWARP)); int mask; if(x < Link->X) mask = 1100b; else mask = 11b; if(Cond(BIG_LINK || IsSideview(),false,true)){ if(Link->Y % 16 < 8) mask &= ~101b; } return (Screen->ComboS[ComboAt(x, Link->Y)]&mask)==0 && !OnLadder(); } // You can customize these functions to suit your needs. // this utility is used to check if link is doing something that would interfer with him using an item. bool LinkBusy() { return (Link->Action==LA_ATTACKING||Link->Action == LA_CHARGING||Link->Action==LA_FROZEN); } // this utility is used to check if link using the feather. bool UseFeather() { return !LinkBusy() && ((GetEquipmentA()==I_ROCSFEATHER && Link->PressA) || (GetEquipmentB()==I_ROCSFEATHER && Link->PressB)); } // this utility is used to check if link is on a sideview ladder. bool OnLadder() { int ct = Screen->ComboT[ComboAt(CenterLinkX(),CenterLinkY())]; return (ct == Cond(CT_LADDER==0,CT_RIGHTSTATUE,CT_LADDER)); } global script slot2_solidffc { void run() { int olddmap = Game->GetCurDMap(); int oldscreen = Game->GetCurScreen(); int startx = Link->X; int starty = Link->Y; int linkxpos = startx; int linkypos = starty; bool dragged; while(true) { if((Link->Action!=LA_SCROLLING) && (olddmap != Game->GetCurDMap() || oldscreen != Game->GetCurScreen())) { olddmap = Game->GetCurDMap(); oldscreen = Game->GetCurScreen(); startx = Link->X; starty = Link->Y; } if(IsSideview()) { //A fix for something I should of done different D: float linkposition = SFFC_SideviewShenanigans(linkxpos, linkypos); linkxpos = linkposition&0xFF; linkypos = (linkposition>>8)&0xFF; if((linkposition%1)*10000) dragged=true; else dragged=false; } Waitdraw(); SolidFFCs(startx, starty, linkxpos, linkypos, dragged); linkxpos = Link->X; linkypos = Link->Y; Waitframe(); } } } //Editing anything beneath this point may cause sickness, coma, brain anuerysm, or death. //Do so at your own risk and don't hold me responsible. Have a good day! ^_^ void SolidFFCs(int startx, int starty, int linkxpos, int linkypos, bool dragged) { int reservedx = Link->X; int reservedy = Link->Y; bool linkmoved[4]; //Up Down Left Right int edge[2]; bool crushed; for(int i = 1; i <= 32 && !crushed; i++) { ffc f = Screen->LoadFFC(i); if(!f->Misc[MISC_SOLIDFFC]) continue; if(!SFFC_LinkCollision(f, edge)) continue; if(!SFFC_SetDirection(f, linkmoved, edge, linkxpos, linkypos)) { crushed = SFFC_CrushLink(f, linkmoved, edge, startx, starty, dragged); continue; } crushed = SFFC_CrushLink(f, linkmoved, edge, startx, starty, dragged); if(!crushed) { if(edge[0]==DIR_UP || edge[0]==DIR_DOWN) { if(!IsSideview()) { SFFC_LinkY += edge[1]; if(Abs(SFFC_LinkY) >= 1) Link->Y += Floor(SFFC_LinkY); SFFC_LinkY -= Floor(SFFC_LinkY); } else if(edge[0]==DIR_UP) { if(!(OnLadder() && UseFeather())) Link->Jump=0; //Negate dat dang gravity } if(Link->InputLeft || Link->InputRight) Link->X = reservedx; } else if(edge[0]==DIR_LEFT ||edge[0]==DIR_RIGHT) { SFFC_LinkX += edge[1]; if(Abs(SFFC_LinkX) >= 1) Link->X += Floor(SFFC_LinkX); SFFC_LinkX -= Floor(SFFC_LinkX); if(Link->InputUp || Link->InputDown || IsSideview()) Link->Y=reservedy; } reservedx=Link->X; reservedy=Link->Y; } } } //As usual Sideview gravity breaks everything even solid ffcs. XD int SFFC_SideviewShenanigans(int linkxpos, int linkypos) { bool linkmoved[4]; //Up Down Left Right int edge[2]; float dragged; for(int i = 1; i <= 32; i++) { ffc f = Screen->LoadFFC(i); if(!f->Misc[MISC_SOLIDFFC]) continue; if(!SFFC_LinkCollision(f, edge) || !SFFC_SetDirection(f, linkmoved, edge, linkxpos, linkypos)) { f->Misc[MISC_SFFC_X] = f->X; continue; } if(edge[0]==DIR_UP) { if(!OnLadder()) { if(UseFeather()) { itemdata feather = Game->LoadItemData(I_ROCSFEATHER); Link->Jump = feather->InitD[0]; Game->PlaySound(feather->UseSound); f->Misc[MISC_SFFC_X] = f->X; break; //Cause it should only happen once per frame. } else { if(Link->Jump<=0) Link->Jump=0; Link->Y = f->Y-16; } linkypos = Link->Y; } if(CanMoveLink(f->X-f->Misc[MISC_SFFC_X])) { SFFC_LinkX += f->X-f->Misc[MISC_SFFC_X]; if(Abs(SFFC_LinkX) >= 1) { Link->X += Floor(SFFC_LinkX); SFFC_LinkX -= Floor(SFFC_LinkX); } linkxpos = Link->X; dragged=0.9999; } else { linkxpos = Link->X; Link->Jump=0; dragged=0; } } else if(edge[0]==DIR_DOWN && Link->Jump>0) { Link->Jump=0; } f->Misc[MISC_SFFC_X] = f->X; } return (linkxpos|(linkypos<<8))+dragged; } //Link Collision bool SFFC_LinkCollision(ffc f, int edge) { int linktop = Link->Y+Cond(BIG_LINK || IsSideview(), 0, 8)>>0; int linkbottom = Link->Y+15>>0; int linkleft = Link->X>>0; int linkright = Link->X+15>>0; int top = HitboxTop(f)>>0; int bottom = HitboxBottom(f)>>0; int left = HitboxLeft(f)>>0; int right = HitboxRight(f)>>0; int mod=0; if(IsSideview()) mod = SFFC_SIDEVIEWTHRESHOLD; // horizontal if(linktop < bottom && linkbottom > top) { if(IsSideview()) mod = 16-mod; //Less math. if(CenterLinkX() < CenterX(f)) // Left Side { edge[0]=DIR_LEFT; return (linkright >= left+mod); } else //Right Side { edge[0]=DIR_RIGHT; return (linkleft <= right-mod); } } // vertical else if(linkleft < right && linkright > left) { if(CenterLinkY() < CenterY(f)) // Top Side { edge[0]=DIR_UP; if(IsSideview()) return linkbottom+1 >= top && (linkleft > left-mod && linkleft < left+mod+(f->TileWidth-1)*16); else return (linkbottom >= top); } else //Bottom Side { edge[0]=DIR_DOWN; return (linktop <= bottom); } } else return false; } bool SFFC_SetDirection(ffc f, bool linkmoved, int edge, int linkxpos, int linkypos) { //Move link to his old position. int x = Link->X; int y = Link->Y; Link->X = linkxpos; Link->Y = linkypos; //Then check for collisions again. bool ret = SFFC_LinkCollision(f, edge); //If we get here we know he didn't walk on the ffc and we got stuff to do. if(edge[0]==DIR_UP) edge[1] = -Abs(HitboxTop(f)-(Link->Y+15)); else if(edge[0]==DIR_DOWN) edge[1] = Abs(HitboxBottom(f)-(Link->Y+Cond(BIG_LINK || IsSideview(),0,8))); else if(edge[0]==DIR_LEFT) edge[1] = -Abs(HitboxLeft(f)-(Link->X+15)); else if(edge[0]==DIR_RIGHT) edge[1] = Abs(HitboxRight(f)-Link->X); linkmoved[edge[0]] = true; if(!ret) { if(Link->X >= HitboxLeft(f)-15 && Link->X <= HitboxRight(f) && (Link->InputLeft||Link->InputRight)) Link->X=x; else if(Link->Y >= HitboxTop(f)-15 && Link->Y+Cond(BIG_LINK || IsSideview(),0,8) <= HitboxBottom(f) && (Link->InputUp||Link->InputDown) || IsSideview()) Link->Y=y; } return ret; } bool SFFC_CrushLink(ffc f, bool linkmoved, int edge, int linkx, int linky, bool dragged) { // Solid Combos bool crush; //Canwalk sucks, do it yourself guys. :) if(!IsSideview()) dragged = false; if(edge[0]==DIR_UP) { crush = isSolid(Floor(CenterLinkX()), Floor(Link->Y+Cond(BIG_LINK || IsSideview(), 0,8)+edge[1])) && !dragged; if(IsSideview() && crush) crush = (Floor(Link->Y)+16+edge[1]>=HitboxTop(f)); //Squash Bug Fix. } else if(edge[0]==DIR_DOWN) crush = isSolid(Floor(CenterLinkX()), Floor(Link->Y+15+edge[1])); else if(edge[0]==DIR_LEFT) crush = isSolid(Floor(Link->X+edge[1]), Floor(Link->Y+Cond(BIG_LINK || IsSideview(), 0,8))); else if(edge[0]==DIR_RIGHT) crush = isSolid(Floor(Link->X+15+edge[1]), Floor(Link->Y+Cond(BIG_LINK || IsSideview(), 0,8))); // Solid FFCs if(!crush) { for(int i; i < 4; i++) { if(linkmoved[i] && i==OppositeDir(edge[0])) { crush=true; break; } } } // Crushing Behavior if(crush) { Link->X = Clamp(linkx,0,240); Link->Y = Clamp(linky,0,160); Link->HP -= CRUSH_DAMAGE; Link->Action = LA_GOTHURTLAND; Link->HitDir = -1; Game->PlaySound(SFX_OUCH); } return crush; } ffc script SolidFFC { void run() { this->Misc[MISC_SOLIDFFC] = 1; this->Misc[MISC_SFFC_X] = this->X; } }
And here is my stuff. I had to double post because the first would be too long.
//Common Constant, only need to define once per script file. const int BIG_LINK = 0; //Set this constant to 1 if using the Large Link Hit Box feature. ///Constants and Variables used by platform script; const int DIAGONAL_MOVEMENT = 1; //Enable the option and change this to 0 for nes movement. int onplatform; //Global variable use this to check if Link is on a platform for other scripts. //Constants used by Bottomless Pits & Lava. const int CT_HOLELAVA = 128; //Combo type to use for pit holes and lava."No Ground Enemies by default" const int CF_PIT = 98; //The combo flag to register combos as pits. const int CF_LAVA = 99; //The combo flag to register combos as lava. const int WPS_LINK_FALL = 91; //The weapon sprite to display when Link falls into a pit. "Sprite 88 by default" const int WPS_LINK_LAVA = 92; //The weapon sprite to display when Link drowns in lava. "Sprite 89 by default" const int SFX_LINK_FALL = 73; //The sound to play when Link falls into a pit. "SFX_FALL by default" const int SFX_LINK_LAVA = 72; //The sound to play when Link drowns in Lava. "SFX_SPLASH by default. const int CMB_AUTOWARP = 936; //The first of your four transparent autowarp combos. const int HOLELAVA_DAMAGE = 8; //Damage in hit points to inflict on link. "One Heart Container is worth 16 hit points" //Constants for Solid FFC const int MISC_SOLIDFFC = 14; //A misc value between 0 and 15 to denote a ffc as solid. const int MISC_SFFC_X = 0; //This can be used by other ffcs as long as they're not solid. const int SFFC_SIDEVIEWTHRESHOLD = 12; //Sideview X Overlap: used for hitdetection. const int CRUSH_DAMAGE = 8; //Damage in 16ths of a heart dealt to link when he is crushed. const int SF_SIDEWARP = 2; //The flag to denote that Left/Right sidewarps are used on a screen. const int CT_LADDER = 0; //If not using CT_RIGHTSTATUE //Global variables used by Bottomless Pits & Lava. int Falling; bool Warping; global script slot2_global { void run() { StartGhostZH(); //Initialize variables used to store Link's strating position on Screen Init. int olddmap = Game->GetCurDMap(); int oldscreen = Game->GetCurDMapScreen(); int oldscreen = Game->GetCurScreen(); int startx = Link->X; int starty = Link->Y; int startdir = Link->Dir; int linkxpos = startx; int linkypos = starty; bool dragged; //Clear global variables used by Bottomless pits. Falling = 0; Warping = false; //Main Loop while(true) { NesMovementFix(); UpdateGhostZH1(); if(onplatform==0) Update_HoleLava(startx, starty, olddmap, oldscreen, startdir); Waitdraw(); MovingPlatforms(); if(Link->Action!=LA_SCROLLING) { if(Link->Z==0 && !Falling && (oldscreen!=Game->GetCurDMapScreen() || olddmap!=Game->GetCurDMap())) { olddmap = Game->GetCurDMap(); oldscreen = Game->GetCurDMapScreen(); startx = Link->X; starty = Link->Y; startdir = Link->Dir; } } UpdateGhostZH2(); Waitframe(); } } } void Update_HoleLava(int x, int y, int dmap, int scr, int dir) { lweapon hookshot = LoadLWeaponOf(LW_HOOKSHOT); if(hookshot->isValid()) return; if(Falling) { if(IsSideview()) Link->Jump=0; Falling--; if(Falling == 1) { int buffer[] = "Holelava"; if(CountFFCsRunning(Game->GetFFCScript(buffer))) { ffc f = Screen->LoadFFC(FindFFCRunning(Game->GetFFCScript(buffer))); Warping = true; if(f->InitD[1]==0) { f->InitD[6] = x; f->InitD[7] = y; } } else { Link->X = x; Link->Y = y; Link->Dir = dir; Link->DrawXOffset -= Cond(Link->DrawXOffset < 0, -1000, 1000); Link->HitXOffset -= Cond(Link->HitXOffset < 0, -1000, 1000); Link->HP -= HOLELAVA_DAMAGE; Link->Action = LA_GOTHURTLAND; Link->HitDir = -1; Game->PlaySound(SFX_OUCH); if(Game->GetCurDMap()!=dmap || Game->GetCurDMapScreen()!=scr) Link->PitWarp(dmap, scr); } } NoAction(); Link->Action = LA_NONE; } else if(Link->Z==0 && OnPitCombo() && !Warping) { Link->DrawXOffset += Cond(Link->DrawXOffset < 0, -1000, 1000); Link->HitXOffset += Cond(Link->HitXOffset < 0, -1000, 1000); int comboflag = OnPitCombo(); SnaptoGrid(); Game->PlaySound(Cond(comboflag == CF_PIT, SFX_LINK_FALL, SFX_LINK_LAVA)); lweapon dummy = CreateLWeaponAt(LW_SCRIPT10, Link->X, Link->Y); dummy->UseSprite(Cond(comboflag == CF_PIT, WPS_LINK_FALL, WPS_LINK_LAVA)); dummy->DeadState = dummy->NumFrames*dummy->ASpeed; dummy->DrawXOffset = 0; dummy->DrawYOffset = 0; Falling = 30; NoAction(); Link->Action = LA_NONE; } } void NesMovementFix() { if(DIAGONAL_MOVEMENT==0 && (Link->InputUp || Link->InputDown)) { Link->InputLeft = false; Link->InputRight = false; } } void MovingPlatforms() { onplatform = 0; if(Link->Z == 0) { int buffer[] = "MovingPlatform"; for(int i = 1; i <= 32; i++) { ffc f = Screen->LoadFFC(i); if(f->Script != Game->GetFFCScript(buffer)) continue; if(Abs(Link->X + 8 - CenterX(f)) >= f->TileWidth*8 + 2) continue; if(Abs(Link->Y + 12 - CenterY(f)) >= f->TileHeight*8 + 2) continue; onplatform = FFCNum(f); break; } } } ffc script Holelava{ void run(int warp, bool position, int damage) { while(true) { while(!Warping) Waitframe(); if(warp > 0) { this->Data = CMB_AUTOWARP+warp-1; this->Flags[FFCF_CARRYOVER] = true; Waitframe(); this->Data = FFCS_INVISIBLE_COMBO; this->Flags[FFCF_CARRYOVER] = false; Link->Z = Link->Y; Warping = false; Link->DrawXOffset -= Cond(Link->DrawXOffset < 0, -1000, 1000); Link->HitXOffset -= Cond(Link->HitXOffset < 0, -1000, 1000); Quit(); } if(position) { Link->X = this->X; Link->Y = this->Y; } else { Link->X = this->InitD[6]; Link->Y = this->InitD[7]; } if(damage) { Link->HP -= damage; Link->Action = LA_GOTHURTLAND; Link->HitDir = -1; Game->PlaySound(SFX_OUCH); } Link->DrawXOffset -= Cond(Link->DrawXOffset < 0, -1000, 1000); Link->HitXOffset -= Cond(Link->HitXOffset < 0, -1000, 1000); Warping = false; Waitframe(); } } } //Used to determine if Link is on a Pit or Lava combo. int OnPitCombo() { int comboLoc = ComboAt(Link->X+8, Link->Y + Cond(BIG_LINK==0, 12, 8)); if(Screen->ComboT[comboLoc] != CT_HOLELAVA) return 0; else if(Screen->ComboI[comboLoc] == CF_PIT || Screen->ComboI[comboLoc] == CF_LAVA) return Screen->ComboI[comboLoc]; else if(Screen->ComboF[comboLoc] == CF_PIT || Screen->ComboF[comboLoc] == CF_LAVA) return Screen->ComboF[comboLoc]; else return 0; } //Snaps Link to the combo so he appears completely over pit and lava combos. void SnaptoGrid() { int x = Link->X; int y = Link->Y + Cond(BIG_LINK==0, 8, 0); int comboLoc = ComboAt(x, y); //X Axis if(Screen->ComboT[comboLoc] == CT_HOLELAVA && Cond(x % 16 == 0, true, Screen->ComboT[comboLoc+1] != CT_HOLELAVA)) Link->X = ComboX(comboLoc); else if(Screen->ComboT[comboLoc+1] == CT_HOLELAVA && Cond(x % 16 == 0, true, Screen->ComboT[comboLoc] != CT_HOLELAVA)) Link->X = ComboX(comboLoc+1); if(Cond(y % 16 == 0, false, Screen->ComboT[comboLoc+16] == CT_HOLELAVA) && Cond(x % 16 == 0, true, Screen->ComboT[comboLoc+17] != CT_HOLELAVA)) Link->X = ComboX(comboLoc+16); else if(Cond(y % 16 == 0, false, Screen->ComboT[comboLoc+17] == CT_HOLELAVA) && Cond(x % 16 == 0, true, Screen->ComboT[comboLoc+16] != CT_HOLELAVA)) Link->X = ComboX(comboLoc+17); //Y Axis if(Screen->ComboT[comboLoc] == CT_HOLELAVA && Cond(y % 16 == 0, true, Screen->ComboT[comboLoc+16] != CT_HOLELAVA)) Link->Y = ComboY(comboLoc); else if(Screen->ComboT[comboLoc+16] == CT_HOLELAVA && Cond(y % 16 == 0, true, Screen->ComboT[comboLoc] != CT_HOLELAVA)) Link->Y = ComboY(comboLoc+16); if(Cond(x % 16 == 0, false, Screen->ComboT[comboLoc+1] == CT_HOLELAVA) && Cond(y % 16 == 0, true, Screen->ComboT[comboLoc+17] != CT_HOLELAVA)) Link->Y = ComboY(comboLoc+1); else if(Cond(x % 16 == 0, false, Screen->ComboT[comboLoc+17] == CT_HOLELAVA) && Cond(y % 16 == 0, true, Screen->ComboT[comboLoc+1] != CT_HOLELAVA)) Link->Y = ComboY(comboLoc+17); } ffc script MovingPlatform{ void run() { float oldx = this->X; float oldy = this->Y; float linkx; float linky; while(true) { if(onplatform == FFCNum(this)) { linkx += this->X - oldx; linky += this->Y - oldy; if(linkx << 0 != 0) { Link->X += linkx << 0; linkx -= linkx << 0; } if(linky << 0 != 0) { Link->Y += linky << 0; linky -= linky << 0; } } else { linkx = 0; linky = 0; } oldx = this->X; oldy = this->Y; Waitframe(); } } } if((Link->Action!=LA_SCROLLING) && (olddmap != Game->GetCurDMap() || oldscreen != Game->GetCurScreen())) { olddmap = Game->GetCurDMap(); oldscreen = Game->GetCurScreen(); startx = Link->X; starty = Link->Y; } if(IsSideview()) { //A fix for something I should of done different D: float linkposition = SFFC_SideviewShenanigans(linkxpos, linkypos); linkxpos = linkposition&0xFF; linkypos = (linkposition>>8)&0xFF; if((linkposition%1)*10000) dragged=true; else dragged=false; } Waitdraw(); SolidFFCs(startx, starty, linkxpos, linkypos, dragged); linkxpos = Link->X; linkypos = Link->Y; Waitframe(); } } } //Editing anything beneath this point may cause sickness, coma, brain anuerysm, or death. //Do so at your own risk and don't hold me responsible. Have a good day! ^_^ void SolidFFCs(int startx, int starty, int linkxpos, int linkypos, bool dragged) { int reservedx = Link->X; int reservedy = Link->Y; bool linkmoved[4]; //Up Down Left Right int edge[2]; bool crushed; for(int i = 1; i <= 32 && !crushed; i++) { ffc f = Screen->LoadFFC(i); if(!f->Misc[MISC_SOLIDFFC]) continue; if(!SFFC_LinkCollision(f, edge)) continue; if(!SFFC_SetDirection(f, linkmoved, edge, linkxpos, linkypos)) { crushed = SFFC_CrushLink(f, linkmoved, edge, startx, starty, dragged); continue; } crushed = SFFC_CrushLink(f, linkmoved, edge, startx, starty, dragged); if(!crushed) { if(edge[0]==DIR_UP || edge[0]==DIR_DOWN) { if(!IsSideview()) { SFFC_LinkY += edge[1]; if(Abs(SFFC_LinkY) >= 1) Link->Y += Floor(SFFC_LinkY); SFFC_LinkY -= Floor(SFFC_LinkY); } else if(edge[0]==DIR_UP) { if(!(OnLadder() && UseFeather())) Link->Jump=0; //Negate dat dang gravity } if(Link->InputLeft || Link->InputRight) Link->X = reservedx; } else if(edge[0]==DIR_LEFT ||edge[0]==DIR_RIGHT) { SFFC_LinkX += edge[1]; if(Abs(SFFC_LinkX) >= 1) Link->X += Floor(SFFC_LinkX); SFFC_LinkX -= Floor(SFFC_LinkX); if(Link->InputUp || Link->InputDown || IsSideview()) Link->Y=reservedy; } reservedx=Link->X; reservedy=Link->Y; } } } //As usual Sideview gravity breaks everything even solid ffcs. XD int SFFC_SideviewShenanigans(int linkxpos, int linkypos) { bool linkmoved[4]; //Up Down Left Right int edge[2]; float dragged; for(int i = 1; i <= 32; i++) { ffc f = Screen->LoadFFC(i); if(!f->Misc[MISC_SOLIDFFC]) continue; if(!SFFC_LinkCollision(f, edge) || !SFFC_SetDirection(f, linkmoved, edge, linkxpos, linkypos)) { f->Misc[MISC_SFFC_X] = f->X; continue; } if(edge[0]==DIR_UP) { if(!OnLadder()) { if(UseFeather()) { itemdata feather = Game->LoadItemData(I_ROCSFEATHER); Link->Jump = feather->InitD[0]; Game->PlaySound(feather->UseSound); f->Misc[MISC_SFFC_X] = f->X; break; //Cause it should only happen once per frame. } else { if(Link->Jump<=0) Link->Jump=0; Link->Y = f->Y-16; } linkypos = Link->Y; } if(CanMoveLink(f->X-f->Misc[MISC_SFFC_X])) { SFFC_LinkX += f->X-f->Misc[MISC_SFFC_X]; if(Abs(SFFC_LinkX) >= 1) { Link->X += Floor(SFFC_LinkX); SFFC_LinkX -= Floor(SFFC_LinkX); } linkxpos = Link->X; dragged=0.9999; } else { linkxpos = Link->X; Link->Jump=0; dragged=0; } } else if(edge[0]==DIR_DOWN && Link->Jump>0) { Link->Jump=0; } f->Misc[MISC_SFFC_X] = f->X; } return (linkxpos|(linkypos<<8))+dragged; } //Link Collision bool SFFC_LinkCollision(ffc f, int edge) { int linktop = Link->Y+Cond(BIG_LINK || IsSideview(), 0, 8)>>0; int linkbottom = Link->Y+15>>0; int linkleft = Link->X>>0; int linkright = Link->X+15>>0; int top = HitboxTop(f)>>0; int bottom = HitboxBottom(f)>>0; int left = HitboxLeft(f)>>0; int right = HitboxRight(f)>>0; int mod=0; if(IsSideview()) mod = SFFC_SIDEVIEWTHRESHOLD; // horizontal if(linktop < bottom && linkbottom > top) { if(IsSideview()) mod = 16-mod; //Less math. if(CenterLinkX() < CenterX(f)) // Left Side { edge[0]=DIR_LEFT; return (linkright >= left+mod); } else //Right Side { edge[0]=DIR_RIGHT; return (linkleft <= right-mod); } } // vertical else if(linkleft < right && linkright > left) { if(CenterLinkY() < CenterY(f)) // Top Side { edge[0]=DIR_UP; if(IsSideview()) return linkbottom+1 >= top && (linkleft > left-mod && linkleft < left+mod+(f->TileWidth-1)*16); else return (linkbottom >= top); } else //Bottom Side { edge[0]=DIR_DOWN; return (linktop <= bottom); } } else return false; } bool SFFC_SetDirection(ffc f, bool linkmoved, int edge, int linkxpos, int linkypos) { //Move link to his old position. int x = Link->X; int y = Link->Y; Link->X = linkxpos; Link->Y = linkypos; //Then check for collisions again. bool ret = SFFC_LinkCollision(f, edge); //If we get here we know he didn't walk on the ffc and we got stuff to do. if(edge[0]==DIR_UP) edge[1] = -Abs(HitboxTop(f)-(Link->Y+15)); else if(edge[0]==DIR_DOWN) edge[1] = Abs(HitboxBottom(f)-(Link->Y+Cond(BIG_LINK || IsSideview(),0,8))); else if(edge[0]==DIR_LEFT) edge[1] = -Abs(HitboxLeft(f)-(Link->X+15)); else if(edge[0]==DIR_RIGHT) edge[1] = Abs(HitboxRight(f)-Link->X); linkmoved[edge[0]] = true; if(!ret) { if(Link->X >= HitboxLeft(f)-15 && Link->X <= HitboxRight(f) && (Link->InputLeft||Link->InputRight)) Link->X=x; else if(Link->Y >= HitboxTop(f)-15 && Link->Y+Cond(BIG_LINK || IsSideview(),0,8) <= HitboxBottom(f) && (Link->InputUp||Link->InputDown) || IsSideview()) Link->Y=y; } return ret; } bool SFFC_CrushLink(ffc f, bool linkmoved, int edge, int linkx, int linky, bool dragged) { // Solid Combos bool crush; //Canwalk sucks, do it yourself guys. :) if(!IsSideview()) dragged = false; if(edge[0]==DIR_UP) { crush = isSolid(Floor(CenterLinkX()), Floor(Link->Y+Cond(BIG_LINK || IsSideview(), 0,8)+edge[1])) && !dragged; if(IsSideview() && crush) crush = (Floor(Link->Y)+16+edge[1]>=HitboxTop(f)); //Squash Bug Fix. } else if(edge[0]==DIR_DOWN) crush = isSolid(Floor(CenterLinkX()), Floor(Link->Y+15+edge[1])); else if(edge[0]==DIR_LEFT) crush = isSolid(Floor(Link->X+edge[1]), Floor(Link->Y+Cond(BIG_LINK || IsSideview(), 0,8))); else if(edge[0]==DIR_RIGHT) crush = isSolid(Floor(Link->X+15+edge[1]), Floor(Link->Y+Cond(BIG_LINK || IsSideview(), 0,8))); // Solid FFCs if(!crush) { for(int i; i < 4; i++) { if(linkmoved[i] && i==OppositeDir(edge[0])) { crush=true; break; } } } // Crushing Behavior if(crush) { Link->X = Clamp(linkx,0,240); Link->Y = Clamp(linky,0,160); Link->HP -= CRUSH_DAMAGE; Link->Action = LA_GOTHURTLAND; Link->HitDir = -1; Game->PlaySound(SFX_OUCH); } return crush; } ffc script SolidFFC { void run() { this->Misc[MISC_SOLIDFFC] = 1; this->Misc[MISC_SFFC_X] = this->X; } }