Advertisement
Guest User

Solid FFCs Alpha 2

a guest
Jan 17th, 2015
305
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
PHP 11.18 KB | None | 0 0
  1. import "std.zh"
  2.  
  3. //Global Constants
  4. const int MISC_SOLIDFFC          = 15; //A misc value between 0 and 15 to denote a ffc as solid.
  5. const int MISC_SFFC_X            = 0;  //This can be used by other scripts.
  6. const int SFFC_SIDEVIEWTHRESHOLD = 12; //Sideview X Overlap: used for hitdetection.
  7. const int CRUSH_DAMAGE           = 8;  //Damage in 16ths of a heart dealt to link when he is crushed.
  8. const int SF_SIDEWARP            = 2;  //The flag to denote that Left/Right sidewarps are used on a screen.
  9. const int BIG_LINK               = 0;
  10. const int CT_LADDER              = 0;  //If not using CT_RIGHTSTATUE
  11.  
  12. //Don't touch me, don't even think about setting these variables. HEY!
  13. float SFFC_LinkX;
  14. float SFFC_LinkY;
  15.  
  16. // this utility routine by Saffith checks for walkability of combos
  17. bool isSolid(int x, int y){
  18.     if(x<0 || x>255 || y<0 || y>175) return false;
  19.     int mask=1111b;
  20.     if(x%16< 8) mask&=0011b;
  21.     else mask&=1100b;
  22.     if(y%16< 8) mask&=0101b;
  23.     else mask&=1010b;
  24.     return (!(Screen->ComboS[ComboAt(x, y)]&mask)==0);
  25. }
  26. // this utility is used by the ffcs to check if the platform can move link.
  27. bool CanMoveLink(int x){
  28.     if(x > 0) x+=Link->X+16;
  29.     else if(x < 0) x+=Link->X-1;
  30.     if(x<0) return (Game->GetCurScreen()%16==0 && ScreenFlag(SF_MISC, SF_SIDEWARP));
  31.     if(x>240) return (Game->GetCurScreen()%16==15 && ScreenFlag(SF_MISC,SF_SIDEWARP));
  32.     int mask;
  33.     if(x < Link->X) mask = 1100b;
  34.     else mask = 11b;
  35.     if(Cond(BIG_LINK || IsSideview(),false,true)){
  36.         if(Link->Y % 16 < 8) mask &= ~101b;
  37.     }
  38.     return (Screen->ComboS[ComboAt(x, Link->Y)]&mask)==0 && !OnLadder();
  39. }
  40.  
  41. // You can customize these functions to suit your needs.
  42. // this utility is used to check if link is doing something that would interfer with him using an item.
  43. bool LinkBusy()
  44. {
  45.     return (Link->Action==LA_ATTACKING||Link->Action == LA_CHARGING||Link->Action==LA_FROZEN);
  46. }
  47.  
  48. // this utility is used to check if link using the feather.
  49. bool UseFeather()
  50. {
  51.     return !LinkBusy() && ((GetEquipmentA()==I_ROCSFEATHER && Link->PressA) || (GetEquipmentB()==I_ROCSFEATHER && Link->PressB));
  52. }
  53.  
  54. // this utility is used to check if link is on a sideview ladder.
  55. bool OnLadder()
  56. {
  57.     int ct = Screen->ComboT[ComboAt(CenterLinkX(),CenterLinkY())];
  58.     return (ct == Cond(CT_LADDER==0,CT_RIGHTSTATUE,CT_LADDER));
  59. }
  60.  
  61. global script slot2_solidffc
  62.  
  63. {
  64.     void run()
  65.     {
  66.         int olddmap = Game->GetCurDMap();
  67.         int oldscreen = Game->GetCurScreen();
  68.         int startx = Link->X;
  69.         int starty = Link->Y;
  70.         int linkxpos = startx;
  71.         int linkypos = starty;
  72.         bool dragged;
  73.         while(true)
  74.         {
  75.             if((Link->Action!=LA_SCROLLING) && (olddmap != Game->GetCurDMap() || oldscreen != Game->GetCurScreen()))
  76.             {
  77.                 olddmap = Game->GetCurDMap();
  78.                 oldscreen = Game->GetCurScreen();
  79.                 startx = Link->X;
  80.                 starty = Link->Y;
  81.             }
  82.             if(IsSideview())
  83.             {
  84.                 //A fix for something I should of done different D:
  85.                 float linkposition = SFFC_SideviewShenanigans(linkxpos, linkypos);
  86.                 linkxpos = linkposition&0xFF;
  87.                 linkypos = (linkposition>>8)&0xFF;
  88.                 if((linkposition%1)*10000) dragged=true;
  89.                 else dragged=false;
  90.             }
  91.             Waitdraw();
  92.             SolidFFCs(startx, starty, linkxpos, linkypos, dragged);
  93.             linkxpos = Link->X;
  94.             linkypos = Link->Y;
  95.             Waitframe();
  96.         }
  97.     }
  98. }
  99.  
  100. //Editing anything beneath this point may cause sickness, coma, brain anuerysm, or death.
  101. //Do so at your own risk and don't hold me responsible. Have a good day! ^_^
  102.  
  103. void SolidFFCs(int startx, int starty, int linkxpos, int linkypos, bool dragged)
  104. {
  105.     int reservedx = Link->X;
  106.     int reservedy = Link->Y;
  107.     bool linkmoved[4]; //Up Down Left Right
  108.     int edge[2];
  109.     bool crushed;
  110.     for(int i = 1; i <= 32 && !crushed; i++)
  111.     {
  112.         ffc f = Screen->LoadFFC(i);
  113.         if(!f->Misc[MISC_SOLIDFFC]) continue;
  114.         if(!SFFC_LinkCollision(f, edge)) continue;
  115.         if(!SFFC_SetDirection(f, linkmoved, edge, linkxpos, linkypos))
  116.         {
  117.             crushed = SFFC_CrushLink(f, linkmoved, edge, startx, starty, dragged);
  118.             continue;
  119.         }
  120.         crushed = SFFC_CrushLink(f, linkmoved, edge, startx, starty, dragged);
  121.         if(!crushed)
  122.         {
  123.             if(edge[0]==DIR_UP || edge[0]==DIR_DOWN)
  124.             {
  125.                 if(!IsSideview())
  126.                 {
  127.                     SFFC_LinkY += edge[1];
  128.                     if(Abs(SFFC_LinkY) >= 1) Link->Y += Floor(SFFC_LinkY);
  129.                     SFFC_LinkY -= Floor(SFFC_LinkY);
  130.                 }
  131.                 else if(edge[0]==DIR_UP)
  132.                 {
  133.                     if(!(OnLadder() && UseFeather()))
  134.                         Link->Jump=0; //Negate dat dang gravity
  135.                 }
  136.                 if(Link->InputLeft || Link->InputRight) Link->X = reservedx;
  137.             }
  138.             else if(edge[0]==DIR_LEFT ||edge[0]==DIR_RIGHT)
  139.             {
  140.                 SFFC_LinkX += edge[1];
  141.                 if(Abs(SFFC_LinkX) >= 1) Link->X += Floor(SFFC_LinkX);
  142.                 SFFC_LinkX -= Floor(SFFC_LinkX);
  143.                 if(Link->InputUp || Link->InputDown || IsSideview()) Link->Y=reservedy;
  144.             }
  145.             reservedx=Link->X;
  146.             reservedy=Link->Y;
  147.         }
  148.     }
  149. }
  150.  
  151. //As usual Sideview gravity breaks everything even solid ffcs. XD
  152. int SFFC_SideviewShenanigans(int linkxpos, int linkypos)
  153. {
  154.     bool linkmoved[4]; //Up Down Left Right
  155.     int edge[2];
  156.     float dragged;
  157.     for(int i = 1; i <= 32; i++)
  158.     {
  159.         ffc f = Screen->LoadFFC(i);
  160.         if(!f->Misc[MISC_SOLIDFFC]) continue;
  161.         if(!SFFC_LinkCollision(f, edge) || !SFFC_SetDirection(f, linkmoved, edge, linkxpos, linkypos))
  162.         {
  163.             f->Misc[MISC_SFFC_X] = f->X;
  164.             continue;
  165.         }
  166.         if(edge[0]==DIR_UP)
  167.         {
  168.              if(!OnLadder())
  169.              {
  170.                  if(UseFeather())
  171.                  {
  172.                      itemdata feather = Game->LoadItemData(I_ROCSFEATHER);
  173.                      Link->Jump = feather->InitD[0];
  174.                      Game->PlaySound(feather->UseSound);
  175.                      f->Misc[MISC_SFFC_X] = f->X;
  176.                      break; //Cause it should only happen once per frame.
  177.                  }
  178.                  else
  179.                  {
  180.                      if(Link->Jump<=0) Link->Jump=0;
  181.                      Link->Y = f->Y-16;
  182.                  }
  183.                  linkypos = Link->Y;
  184.              }
  185.              if(CanMoveLink(f->X-f->Misc[MISC_SFFC_X]))
  186.              {
  187.                  SFFC_LinkX += f->X-f->Misc[MISC_SFFC_X];
  188.                  if(Abs(SFFC_LinkX) >= 1)
  189.                  {
  190.                      Link->X += Floor(SFFC_LinkX);
  191.                      SFFC_LinkX -= Floor(SFFC_LinkX);
  192.                  }
  193.                  linkxpos = Link->X;
  194.                  dragged=0.9999;
  195.              }
  196.              else
  197.              {
  198.                  linkxpos = Link->X;
  199.                  Link->Jump=0;
  200.                  dragged=0;
  201.              }
  202.         }
  203.         else if(edge[0]==DIR_DOWN && Link->Jump>0)
  204.         {
  205.             Link->Jump=0;
  206.         }
  207.         f->Misc[MISC_SFFC_X] = f->X;
  208.     }
  209.     return (linkxpos|(linkypos<<8))+dragged;
  210. }
  211.  
  212. //Link Collision
  213. bool SFFC_LinkCollision(ffc f, int edge)
  214. {
  215.     int linktop = Link->Y+Cond(BIG_LINK || IsSideview(), 0, 8)>>0;
  216.     int linkbottom = Link->Y+15>>0;
  217.     int linkleft = Link->X>>0;
  218.     int linkright = Link->X+15>>0;
  219.     int top = HitboxTop(f)>>0;
  220.     int bottom = HitboxBottom(f)>>0;
  221.     int left = HitboxLeft(f)>>0;
  222.     int right = HitboxRight(f)>>0;
  223.     int mod=0;
  224.     if(IsSideview()) mod = SFFC_SIDEVIEWTHRESHOLD;
  225.     // horizontal
  226.     if(linktop < bottom && linkbottom > top)
  227.     {
  228.         if(IsSideview()) mod = 16-mod; //Less math.
  229.         if(CenterLinkX() < CenterX(f)) // Left Side
  230.         {
  231.             edge[0]=DIR_LEFT;
  232.             return (linkright >= left+mod);
  233.         }
  234.         else //Right Side
  235.         {
  236.             edge[0]=DIR_RIGHT;
  237.             return (linkleft <= right-mod);
  238.         }
  239.     }
  240.     // vertical
  241.     else if(linkleft < right && linkright > left)
  242.     {
  243.         if(CenterLinkY() < CenterY(f)) // Top Side
  244.         {
  245.             edge[0]=DIR_UP;
  246.             if(IsSideview()) return linkbottom+1 >= top;
  247.             else return (linkbottom >= top);
  248.         }
  249.         else //Bottom Side
  250.         {
  251.             edge[0]=DIR_DOWN;
  252.             return (linktop <= bottom);
  253.         }
  254.     }
  255.     else return false;
  256. }
  257.  
  258. bool SFFC_SetDirection(ffc f, bool linkmoved, int edge, int linkxpos, int linkypos)
  259. {
  260.     //Move link to his old position.
  261.     int x = Link->X;
  262.     int y = Link->Y;
  263.     Link->X = linkxpos;
  264.     Link->Y = linkypos;
  265.     //Then check for collisions again.
  266.     bool ret = SFFC_LinkCollision(f, edge);
  267.     //If we get here we know he didn't walk on the ffc and we got stuff to do.
  268.     if(edge[0]==DIR_UP) edge[1] = -Abs(HitboxTop(f)-(Link->Y+15));
  269.     else if(edge[0]==DIR_DOWN) edge[1] = Abs(HitboxBottom(f)-(Link->Y+Cond(BIG_LINK || IsSideview(),0,8)));
  270.     else if(edge[0]==DIR_LEFT) edge[1] = -Abs(HitboxLeft(f)-(Link->X+15));
  271.     else if(edge[0]==DIR_RIGHT) edge[1] = Abs(HitboxRight(f)-Link->X);
  272.     linkmoved[edge[0]] = true;
  273.     if(!ret)
  274.     {
  275.         if(Link->X >= HitboxLeft(f)-15 && Link->X <= HitboxRight(f) &&
  276.           (Link->InputLeft||Link->InputRight)) Link->X=x;
  277.         else if(Link->Y >= HitboxTop(f)-15 && Link->Y+Cond(BIG_LINK || IsSideview(),0,8) <= HitboxBottom(f) &&
  278.           (Link->InputUp||Link->InputDown) || IsSideview()) Link->Y=y;
  279.     }
  280.     return ret;
  281. }
  282.  
  283. bool SFFC_CrushLink(ffc f, bool linkmoved, int edge, int linkx, int linky, bool dragged)
  284. {
  285.     // Solid Combos
  286.     bool crush; //Canwalk sucks, do it yourself guys. :)
  287.     if(!IsSideview()) dragged = false;
  288.     if(edge[0]==DIR_UP)
  289.     {
  290.          crush = isSolid(Floor(CenterLinkX()), Floor(Link->Y+Cond(BIG_LINK || IsSideview(), 0,8)+edge[1])) && !dragged;
  291.          if(IsSideview() && crush) crush = (Floor(Link->Y)+16+edge[1]>=HitboxTop(f)); //Squash Bug Fix.
  292.     }
  293.     else if(edge[0]==DIR_DOWN)
  294.          crush = isSolid(Floor(CenterLinkX()), Floor(Link->Y+15+edge[1]));
  295.     else if(edge[0]==DIR_LEFT)
  296.          crush = isSolid(Floor(Link->X+edge[1]), Floor(Link->Y+Cond(BIG_LINK || IsSideview(), 0,8)));
  297.     else if(edge[0]==DIR_RIGHT)
  298.          crush = isSolid(Floor(Link->X+15+edge[1]), Floor(Link->Y+Cond(BIG_LINK || IsSideview(), 0,8)));
  299.     // Solid FFCs
  300.     if(!crush)
  301.     {
  302.         for(int i; i < 4; i++)
  303.         {
  304.             if(linkmoved[i] && i==OppositeDir(edge[0]))
  305.             {
  306.                 crush=true;
  307.                 break;
  308.             }
  309.         }
  310.     }
  311.     // Crushing Behavior
  312.     if(crush)
  313.     {
  314.         Link->X = Clamp(linkx,0,240);
  315.         Link->Y = Clamp(linky,0,160);
  316.         Link->HP -= CRUSH_DAMAGE;
  317.         Link->Action = LA_GOTHURTLAND;
  318.         Link->HitDir = -1;
  319.         Game->PlaySound(SFX_OUCH);
  320.     }
  321.     return crush;
  322. }
  323.  
  324. ffc script SolidFFC
  325. {
  326.     void run()
  327.     {
  328.         this->Misc[MISC_SOLIDFFC] = 1;
  329.         this->Misc[MISC_SFFC_X] = this->X;
  330.     }
  331. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement