Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- import "std.zh"
- //Global Constants
- const int MISC_SOLIDFFC = 15; //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 scripts.
- 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;
- 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;
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement