Advertisement
Guest User

Dark Link

a guest
Nov 24th, 2015
78
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 18.29 KB | None | 0 0
  1. //import "std.zh"
  2. //import "string.zh"
  3. //import "ghost.zh"
  4.  
  5. // Used by otherscripts most likely
  6. const int COLOR_WHITE = 1;
  7.  
  8. // Idle Settings
  9. const int DARKLINK_MIN_IDLE_TIME = 48;
  10. const int DARKLINK_MAX_IDLE_TIME = 96;
  11.  
  12. // Rush Settings
  13. const int DARKLINK_MIN_ATTACK_FACTOR = .5; // Used with haltrate
  14. const int DARKLINK_MAX_ATTACK_FACTOR = 1.5; // Used with haltrate
  15.  
  16. // Dodge Settings
  17. const int DARKLINK_DODGE_STEP = 0.8;
  18. const int DARKLINK_SHIELDED = 1; // Shield is unbreakable and handled manually do to it being toggled when it attacks
  19.  
  20. // Jump Settings
  21. const float DARKLINK_JUMP_VELOCITY = 3.2; // Jump Velocity
  22. const float DARKLINK_JUMP_STEP = 1;
  23.  
  24. // Charge Settings
  25. const float DARKLINK_CHARGE_STEP = 1;
  26.  
  27. // Attack settings
  28. const float DARKLINK_ATTACK_DISTANCE = 24.0; // Distance to Link's Center to DarkLink's Center
  29. const int DARKLINK_CAN_SLASH = 1; //includes spin attacks
  30. const int DARKLINK_SWORD_FLIP_FIX = 1; //set this to one if Links down facing sword is flipped horizontally and not just veritcally.
  31. const int DARKLINK_SLASH_FLIP_FIX = 0; //set this to one if Links right slash tile is flipped
  32.  
  33. // Special Attack settings
  34. const int DARKLINK_NORMAL_CHARGE_TIME = 64; // ZC Default is 64 "Spin Attack"
  35. const int DARKLINK_MAGIC_CHARGE_TIME = 192; // ZC Default is 192 "Hurricane Spin and Quake Thrust"
  36.  
  37. // Spin Attack Settings
  38. const float DARKLINK_SPIN_DAMAGE_MULTIPLIER = 2;
  39.  
  40. // Hurricane Spin settings
  41. const float DARKLINK_HSPIN_DAMAGE_MULTIPLIER = 2;
  42. const int DARKLINK_HSPIN_COUNT = 20;
  43.  
  44. // Quake Thrust settings
  45. const float DARKLINK_QTHRUST_DAMAGE_MULTIPLIER = 2;
  46. const int DARKLINK_QTHRUST_SPEED = 8;
  47. const int DARKLINK_QTHRUST_MIN_TIME = 240;
  48. const int DARKLINK_QTHRUST_MAX_TIME = 320;
  49. const int DARKLINK_QTHRUST_QUAKE_TIME = 90; // Shake the screen for this amount
  50.  
  51. // Default settings (can be overridden by attributes)
  52. const int DARKLINK_DEFAULT_SIZE = 1; // 1, 2, or 3 "1x1, 1x2, 2x2 respectfully"
  53. const int DARKLINK_DEFAULT_HITBOX = 0; // 0 false, 1 true "same as the big link hit box"
  54. const int DARKLINK_DEFAULT_DEBRIS_SPRITE = 18;
  55. const int DARKLINK_DEFAULT_STUN_TIME = 90;
  56. const int DARKLINK_DEFAULT_DEBRIS_DAMAGE = 16; // Overridden by weapon damage
  57.  
  58. // npc->Attributes[] indices
  59. //const int DARKLINK_ATTR_SIZE = 0;
  60. //const int DARKLINK_ATTR_BIGLINK = 1;
  61. const int DARKLINK_ATTR_FLAGS = 2;
  62. const int DARKLINK_ATTR_STUN_TIME = 3;
  63. const int DARKLINK_ATTR_DROPPED_OBJECT = 4;
  64. const int DARKLINK_ATTR_SFX_JUMP = 5;
  65. const int DARKLINK_ATTR_SFX_QTHRUST = 6;
  66. const int DARKLINK_ATTR_DEBRIS_SPRITE = 7;
  67. const int DARKLINK_ATTR_SWORD_SPRITE = 8; // You must provide this on your own.
  68. const int DARKLINK_ATTR_DEATH_TYPE = 9;
  69.  
  70. // ffc->Misc[] indices
  71. const int DARKLINK_IDX_BASE_COMBO = 0;
  72. const int DARKLINK_IDX_KNOCKBACK = 1;
  73. const int DARKLINK_IDX_LINK_STUN_TIME = 2;
  74.  
  75. // Combo offsets "4 combos each facing up down left right, they ignore direction if negative, and can share the same value if desired"
  76. const int DARKLINK_CMB_IDLE = 0;
  77. const int DARKLINK_CMB_RUSH = 1;
  78. const int DARKLINK_CMB_DODGE   = 2;
  79. const int DARKLINK_CMB_JUMP = 3;
  80. const int DARKLINK_CMB_CHARGE  = 4;
  81. const int DARKLINK_CMB_SLASH   = 5;
  82. const int DARKLINK_CMB_STAB = 6;
  83. const int DARKLINK_CMB_SPIN = 7; // Both this and below should not be animated it is done manually and takes 4 or 8 combos depending if you enable DARKLINK_CAN_SLASH
  84. const int DARKLINK_CMB_HSPIN   = 7; // HSpin should use the same combos as spin attack unless you desire otherwise.
  85. const int DARKLINK_CMB_QTHRUST = -9;
  86.  
  87. // Flags
  88. const int DARKLINK_FLAG_FREEZABLE = 00000001b; // 1
  89. const int DARKLINK_FLAG_NO_HSPIN =   00000010b; // 2
  90. const int DARKLINK_FLAG_NO_QTHRUST =   00000100b; // 4
  91. const int DARKLINK_FLAG_STUN_LINK = 00000100b; // 8
  92. const int DARKLINK_FLAG_DEBRIS =       00001000b; // 16
  93. const int DARKLINK_FLAG_DROP_OBJECTS = 00010000b; // 32
  94. const int DARKLINK_FLAG_UNBLOCKABLE =  01000000b; // 64
  95. const int DARKLINK_FLAG_INTRO =     10000000b; // 128
  96.  
  97. //Misc DO NOT CHANGE THESE
  98. const int DARKLINK_SWORDCHARGEFRAME= 20;
  99. ffc script Darklink
  100. {
  101.     void run(int enemyID)
  102.     {
  103.         npc ghost=Ghost_InitAutoGhost(this, enemyID);
  104.        
  105.         if((ghost->Attributes[DARKLINK_ATTR_FLAGS]&DARKLINK_FLAG_FREEZABLE)!=0)
  106.         {
  107.             Ghost_SetFlag(GHF_STUN);
  108.             Ghost_SetFlag(GHF_CLOCK);
  109.         }
  110.        
  111.         this->Misc[DARKLINK_IDX_BASE_COMBO]=Ghost_Data;
  112.        
  113. //      int defenses[18];
  114. //      if(DARKLINK_SHIELDED)
  115. //      {
  116. //          Ghost_StoreDefenses(ghost, defenses);
  117. //          Ghost_SetAllDefenses(ghost, NPCDT_BLOCK);
  118. //      }
  119.        
  120.         if((ghost->Attributes[DARKLINK_ATTR_FLAGS]&DARKLINK_FLAG_INTRO)!=0)
  121.             DoIntro(this, ghost);
  122.         else if(Ghost_Z==0)
  123.             Ghost_SpawnAnimationPuff(this, ghost);
  124.         else // Dropping from the ceiling?
  125.         {
  126.             while(Ghost_Z>0)
  127.                 DLWaitframe(this, ghost);
  128.         }
  129.        
  130.         int superattack;
  131.         int spinchance=-1;
  132.         int hspinchance=-1;
  133.         int qthrustchance=-1;
  134.  
  135.         int i;
  136.         while(true) //Behavior it self
  137.         {
  138.             //Stand there like an idiot
  139.             Idle(this,ghost);
  140.            
  141.             //Rush,Attack,Dodge loop
  142.             int i;
  143.             if(i==0)
  144.                 i=1;
  145.             for(;i>0; i--)
  146.             {
  147.                 Ghost_SetFlag(GHF_SET_DIRECTION);
  148.                 Rush(this,ghost);
  149.                 Ghost_UnsetFlag(GHF_SET_DIRECTION);
  150.                 if(Attack(this,ghost));
  151.                     Dodge(this, ghost);
  152.                 else
  153.                     Jump(this,ghost);
  154.             }
  155.            
  156.             //Super Attack!
  157.             if((ghost->Attributes[DARKLINK_ATTR_FLAGS]&DARKLINK_FLAG_NO_HSPIN)==0)
  158.             {
  159.                 if((ghost->Attributes[DARKLINK_ATTR_FLAGS]&DARKLINK_FLAG_NO_QTHRUST)==0)
  160.                 {
  161.                     spinchance=2
  162.                     hspinchance=4
  163.                     qthrustchance=6
  164.                 }
  165.                 else
  166.                 {
  167.                     spinchance=3
  168.                     hspinchance=6
  169.                 }
  170.             }
  171.             if((ghost->Attributes[DARKLINK_ATTR_FLAGS]&DARKLINK_FLAG_NO_QTHRUST)==0)
  172.             {
  173.                 if((ghost->Attributes[DARKLINK_ATTR_FLAGS]&DARKLINK_FLAG_NO_HSPIN)!=0)
  174.                 {
  175.                     spinchance=3
  176.                     qthrustchance=6
  177.                 }
  178.             }
  179.             superattack=Rand(6);
  180.             if(superattack<spinchance)
  181.             {
  182.                 eweapon sword=Charge(this,ghost,DARKLINK_SPIN_CHARGE_TIME, true);
  183.                 SpinAttack(this,ghost,sword,false);
  184.             }
  185.             else if(superattack<hspinchance)
  186.             {
  187.                 eweapon sword=Charge(this,ghost,DARKLINK_HSPIN_CHARGE_TIME, true);
  188.                 SpinAttack(this,ghost,sword,true);
  189.             }
  190.             else if(superattack<qthrust)
  191.             {
  192.                 Ghost_Dir=DIR_DOWN;
  193.                 QuakeThrust(this,ghost,sword);
  194.             }
  195.         }
  196.     }
  197.     void Idle(ffc this, npc ghost)
  198.     {
  199.         Ghost_Data=GetComboOffset(this, DARKLINK_CMB_IDLE);
  200.         for(int i=Rand(DARKLINK_MIN_IDLE_TIME,DARKLINK_MAX_IDLE_TIME);; i>0; i--)
  201.             DLWaitframe(this,ghost);
  202.     }
  203.     void Rush(ffc this, npc ghost)
  204.     {
  205.         Ghost_Data=GetComboOffset(this, DARKLINK_CMB_RUSH);
  206.         //Rush at Link
  207.         do
  208.         {
  209.             Ghost_MoveTowardLink(ghost->Step/100,3);
  210.             DLWaitframe(this,ghost);
  211.         } while(DLDistanceTo(LinkCenterX(),LinkCenterY())>DARKLINK_ATTACK_DISTANCE);
  212.     }
  213.     bool Attack(ffc this, npc ghost)
  214.     {
  215.         eweapon sword = FireEWeapon(EW_SCRIPT1, Ghost_X, Ghost_Y, 0, 0, ghost->WeaponDamage, ghost->Attributes[DARKLINK_ATTR_SWORD_SPRITE], SFX_SWORD, EWF_NO_COLLISION);
  216.         int dir=Ghost_Dir;
  217.         for(int i=1; i <= 14; i++)
  218.         {
  219.             //set combo
  220.             if(DARKLINK_SLASH&&i<6)
  221.                 Ghost_Data=GetComboOffset(this, DARKLINK_CMB_SLASH);
  222.             else
  223.                 Ghost_Data=GetComboOffset(this, DARKLINK_CMB_STAB);
  224.             //Updating the sword itself is handled separately
  225.             UpdateSword()
  226.             DLSwordWaitframe(this,ghost,sword);
  227.             if(Ghost_GotHit())
  228.                 break;
  229.         }
  230.         if(sword->isValid())
  231.             sword->DeadState=WDS_DEAD;
  232.         return Ghost_GotHit());
  233.     }
  234.     void Dodge(ffc this, npc ghost)
  235.     {
  236.         Ghost_Data=GetComboOffset(this, DARKLINK_CMB_DODGE);
  237.         float linkangle=ArcTan(DLCenterX()-LinkCenterX(),DLCenterY()-LinkCenterY());
  238.         Ghost_Jump=2.8;
  239.         Game->PlaySound(ghost->Attributes[DARKLINK_ATTR_SFX_JUMP]);
  240.         while(Ghost_Z>0 || Ghost_Jump>0)
  241.         {
  242.             Ghost_MoveAtAngle(linkangle,DARKLINK_JUMP_STEP*(ghost->Step/100),3);
  243.             Ghost_ForceDir(OppositeDir(RadianAngleDir4(linkangle));
  244.         }  
  245.     }
  246.     void Jump(ffc this, npc ghost)
  247.     {
  248.         int dir=JumpDirection();
  249.         if(dir==-1)
  250.             return(Dodge(this,ghost)); //this happens vary rarely
  251.    
  252.         Ghost_Jump=DARKLINK_JUMP_VELOCITY;
  253.         Game->PlaySound(ghost->Attributes[DARKLINK_ATTR_SFX_JUMP]);
  254.         while(Ghost_Z>0 || Ghost_Jump>0)
  255.         {
  256.             Ghost_Move(dir,DARKLINK_JUMP_STEP*(ghost->Step/100),3);
  257.             Ghost_ForceDir(OppositeDir(dir);
  258.         }
  259.     }
  260.     eweapon Charge(ffc this, npc ghost, int time, bool move)
  261.     {
  262.         //TODO
  263.     }
  264.     void SpinAttack(ffc this, npc ghost, eweapon sword, bool hurricane)
  265.     {
  266.         int attackclk=1;
  267.         int spins = Cond(hurricane,(DARKLINK_HSPIN_COUNT*4)-3,(DARKLINK_SPIN_COUNT*4)+1);
  268.         int charging = Cond(hurricane,DARKLINK_MAGIC_CHARGE_TIME, DARKLINK_NORMAL_CHARGE_TIME);
  269.    
  270.         // Faster if spinning.
  271.         for(;spins>0;spins--)
  272.         {
  273.             attackclk+=Cond(hurricane,4,2);
  274.             Ghost_Data=GetComboOffset(this,Cond(hurricane,DARLINK_CMB_SPIN,DARKLINK_CMB_HSPIN));
  275.             if(DARKLINK_CAN_SLASH && attackclk>=7 && attackclk<11)
  276.                 Ghost_Data+=4;
  277.             if(hurricane) Ghost_MoveTowardLink(ghost->Step/100,3);
  278.             sword=UpdateSword(sword,charging,attackclk,ghost,spins);
  279.             Spin(spins);
  280.             DLSwordWaitframe(this,ghost,sword);
  281.         }
  282.         sword->DeadState=WDS_DEAD;
  283.     }
  284.     void Spin(int spins)
  285.     {
  286.         if(spins>1)
  287.         {
  288.             if(spins%5==0)
  289.             {
  290.            
  291.                 attackclk=1;
  292.                 if(Ghost_Dir==DIR_UP)
  293.                     Ghost_Dir=DIR_LEFT;
  294.                 else if(Ghost_Dir==DIR_DOWN)
  295.                     Ghost_Dir=DIR_UP;
  296.                 else if(Ghost_Dir==DIR_DOWN)
  297.                     Ghost_Dir=DIR_RIGHT
  298.                 else if(Ghost_Dir==DIR_LEFT)
  299.                     Ghost_Dir=DIR_DOWN;
  300.                 else
  301.                     spins=0;
  302.             }
  303.         }
  304.     }
  305.     void QuakeThrust(ffc this, npc ghost, eweapon sword)
  306.     {
  307.         //TODO
  308.     }
  309.     void DoIntro(ffc this, npc ghost)
  310.     {
  311.         Ghost_Data=GH_INVISIBLE_COMBO;
  312.         //Flash Screen
  313.         for(int i; i<60; i++) //2 seconds
  314.         {
  315.             Rectangle(6,0,0,256,176,COLOR_WHITE,-1, 0,0,0,true,128);
  316.             for(int j; j < 2; j++)
  317.             {
  318.                 NoAction()
  319.                 Ghost_WaitframeLight(this,ghost);
  320.             }
  321.         }
  322.         Ghost_Data=ghost->Attributes[11]+GetComboOffset(this, DARKLINK_CMB_DODGE);
  323.         Ghost_X=Link->X;
  324.         Ghost_Y=Link->Y;
  325.         ghost->CollDetection=false
  326.         Ghost_Dir=OppositeDir(Link->Dir);
  327.         Ghost_Jump=DARKLINK_JUMP_VELOCITY*.75;
  328.         while(Ghost_Jump>0 || Ghost_Z>0)
  329.         {
  330.             NoAction();
  331.             Ghost_ForceDir(OppositeDir(Link->Dir));
  332.             Ghost_Move(OppositeDir(Ghost_Dir),(DARKLINK_JUMP_STEP*ghost->Step)/100,3);
  333.             DLWaitframe(this,ghost);
  334.         }
  335.         ghost->CollDetection=true;
  336.     }
  337.     void DLWaitframe(ffc this, npc ghost)
  338.     {
  339.         if(this->Misc[DARKLINK_IDX_LINK_STUN_TIME]>0)
  340.         {
  341.             NoAction();
  342.             this->Misc[DARKLINK_IDX_LINK_STUN_TIME]--;
  343.         }
  344.         if((this->Misc[DARKLINK_IDX_KNOCKBACK]%1)/10000)
  345.         {
  346.             int counter=(this->Misc[DARKLINK_IDX_KNOCKBACK]%1)/10000;
  347.             counter;
  348.             Ghost_MoveAtAngle(this->Misc[DARKLINK_IDX_KNOCKBACK]>>0,2,3);
  349.         }      
  350.         bool noDeathAnim=ghost->Attributes[DARKLINK_ATTR_DEATH_TYPE]==0;
  351.         if(!Ghost_Waitframe(this, ghost, noDeathAnim, noDeathAnim))
  352.         {
  353.             if(ghost->Attributes[DARKLINK_ATTR_DEATH_TYPE]!=-1)
  354.                 Ghost_DeathAnimation(this, ghost, ghost->Attributes[BTEK_ATTR_DEATH_TYPE]);
  355.             else
  356.                 Dissolve(this, ghost, false);
  357.             Quit();
  358.         }
  359.     }
  360.     void DLSwordWaitframe(ffc this, npc ghost, eweapon sword)
  361.     {
  362.         if(this->Misc[DARKLINK_IDX_LINK_STUN_TIME]>0)
  363.         {
  364.             NoAction();
  365.             this->Misc[DARKLINK_IDX_LINK_STUN_TIME]--;
  366.         }
  367.         if((this->Misc[DARKLINK_IDX_KNOCKBACK]%1)/10000)
  368.         {
  369.             int counter=((this->Misc[DARKLINK_IDX_KNOCKBACK]%1)/10000)--;
  370.             float oldx=Ghost_X;
  371.             float oldy=Ghost_Y;
  372.             Ghost_MoveAtAngle(this->Misc[DARKLINK_IDX_KNOCKBACK]>>0,1,3);
  373.             sword->X+=oldx-Ghost_X;
  374.             sword->Y+=oldy-Ghost_Y;
  375.             this->Misc[DARKLINK_IDX_KNOCKBACK]=Floor(this->Misc[DARKLINK_IDX_KNOCKBACK])+counter;
  376.         }
  377.         bool noDeathAnim=ghost->Attributes[DARKLINK_ATTR_DEATH_TYPE]==0;
  378.         if(!Ghost_Waitframe(this, ghost, noDeathAnim, noDeathAnim))
  379.         {
  380.             sword->DeadState=WDS_DEAD;
  381.             if(ghost->Attributes[DARKLINK_ATTR_DEATH_TYPE]!=-1)
  382.                 Ghost_DeathAnimation(this, ghost, ghost->Attributes[BTEK_ATTR_DEATH_TYPE]);
  383.             else
  384.                 Dissolve(this, ghost, false);
  385.             Quit();
  386.         }
  387.     }
  388.     void Dissolve(ffc this, npc ghost, bool flash)
  389.     {
  390.         int baseX=Ghost_X+ghost->DrawXOffset;
  391.         int baseY=(Ghost_Y+ghost->DrawYOffset)-(Ghost_Z+ghost->DrawZOffset);
  392.        
  393.         __DeathAnimStart(this, ghost);
  394.         __DeathAnimSFX(ghost->ID, ghost->X);
  395.    
  396.         if(flash)
  397.             __Ghost_FlashCounter=10000;
  398.         else
  399.             __Ghost_FlashCounter=0;
  400.            
  401.         ghost->DrawXOffset=1000;
  402.        
  403.         int x;
  404.         int y;
  405.         int layer=Cond(Screen->Flags[SF_VIEW]&10000b)!=0,1,2);
  406.         bool pixel[256];
  407.         //16 pixels every 16 frames
  408.         for(int i; i < 16; i++)
  409.         {
  410.             Screen->SetRenderTarget(RT_BITMAP6);
  411.             Screen->FastCombo(2,baseX,baseY,Ghost_Data+Ghost_Dir,ghost->CSet,128);
  412.             for(int j; j < 16; j++)
  413.             {
  414.                 while(true) //ack...
  415.                 {
  416.                     x=Rand(16);
  417.                     y=Rand(16);
  418.                     if(!pixel[x+(y*16)])
  419.                         break;
  420.                     else // o_O
  421.                     {
  422.                         x=Rand(16);
  423.                         if(!pixel[x+(y*16)])
  424.                             break;
  425.                         y=Rand(16);
  426.                         if(!pixel[x+(y*16)])
  427.                             break;
  428.                     }
  429.                 }
  430.                 pixel[x+(y*16)]=true;
  431.                 Screen->PutPixel(3,baseX+x,baseY+y,0,0,0,0,128);
  432.             }
  433.             Screen->SetRenderTarget(RT_SCREEN);
  434.  
  435.             for(int j; j<16; j++)
  436.             {
  437.                 Screen->rawBitmap(layer, RT_BITMAP6, baseX, baseY, 16, 16, baseX, baseY, 16, 16, false, true);
  438.                 Ghost_WaitframeLight(this,ghost);
  439.             }
  440.         }      
  441.         __DeathAnimEnd(this, ghost);
  442.     }
  443.     int JumpDirection()
  444.     {
  445.         int top = Link->Y
  446.         int bottom = Link->Y+15;
  447.         int left = Link->X;
  448.         int right = Link->X+15;
  449.         int b=32; //2/3 of this is used for the y axis
  450.            
  451.         if(Abs(DTCenterY()-LinkCenterY()<Abs(DTCenterX()-LinkCenterX()) // Horizontal Jump
  452.         {
  453.             if(left<32+b || right > 224-b) // Too close jump away
  454.                 return RadianAngleDir4(ArcTan(DLCenterX()-LinkCenterX(),0));
  455.             else // Too far jump towards
  456.                 return RadianAngleDir4(ArcTan(LinkCenterX()-DLCenterX()(),0));
  457.         }
  458.         else if(Abs(DTCenterX()-LinkCenterX()>Abs(DTCenterX()-LinkCenterX())
  459.         {
  460.             if(left<32+b || right > 224-b) // Too close jump away
  461.                 return RadianAngleDir4(ArcTan(0,DLCenterY()-LinkCenterY()));
  462.             else // Too far jump towards
  463.                 return RadianAngleDir4(ArcTan(0,LinkCenterY()-DLCenterY()));
  464.         }
  465.         else //rare occasion just dodge return -1 and Dodge as a result.
  466.             return -1;
  467.     }  
  468.     eweapon UpdateSword(eweapon sword, int attackclk, int charging, int spins, npc ghost)
  469.     {
  470.         if(attackclk>4||DARKLINK_CAN_SLASH)
  471.         {
  472.             if(!sword->isValid())  // Create one if sword nonexistant
  473.                 sword=eweapon sword = FireEWeapon(EW_SCRIPT1, Ghost_X, Ghost_Y, 0, 0, ghost->WeaponDamage, ghost->Attributes[DARKLINK_ATTR_SWORD_SPRITE], SFX_SWORD, EWF_NO_COLLISION);
  474.             sword->DeadState=WDS_ALIVE;
  475.             PositionSword(sword,attackclk);
  476.         }
  477.         if(!charging && !spins)  // remove the sword
  478.             sword->DeadState=WDS_DEAD;
  479.         else
  480.         {           //check for collision
  481.             lweapon linksword=LoadLWeaponOf(LW_SWORD);
  482.             if(!((this->Misc[DARKLINK_IDX_KNOCKBACK]%1)*10000)
  483.             {
  484.                 if(Collision(sword,linksword))
  485.                 {
  486.                     this->Misc[DARKLINK_IDX_KNOCKBACK]=Angle(linksword->X,linksword->Y,sword->X,sword->Y)>>0 + (32/10000);
  487.                     Game->PlaySound(SFX_CLINK);
  488.                 }
  489.             }
  490.             if(LinkCollision(sword) && Link->CollDetection)
  491.             {
  492.                 Link->HP-ghost->WeaponDamage*4;
  493.                 Link->Action=LA_GOTHURTLAND;
  494.                 Link->HitDir=RadianAngleDir4(ArcTan(Link->X-sword->X,Link->Y-sword->Y));
  495.                 Game->Sound(SFX_OUCH);
  496.             }
  497.         }
  498.         return sword;
  499.     }
  500.     void PositionSword(eweapon w, int attackclk, int charging, int spins)
  501.     {
  502.         int wx=1;
  503.         int wy=1;
  504.         int t=sword->OriginalTile;
  505.         int f=0;
  506.    
  507.         if(Ghost_Dir==DIR_UP)
  508.         {
  509.             wx=-1;
  510.             wy=-12;
  511.             if(DARKLINK_CAN_SLASH && !charging)
  512.             {
  513.                 if(attackclk>10) //extended stab
  514.                     wy-=2;
  515.            
  516.                 if(attackclk>=14) //retracting stab
  517.                     wy+=2;
  518.             }
  519.             else
  520.             {
  521.                 if(attackclk==DARKLINK_SWORDCHARGEFRAME)
  522.                     wy+=4;
  523.                 else if(attackclk==13)
  524.                     wy+=4;
  525.                 else if(attackclk==14)
  526.                     wy+=8;
  527.             }
  528.         }
  529.         else if(Ghost_Dir==DIR_DOWN)
  530.         {
  531.             f=Cond(DARKLINK_SWORD_FLIP_FIX!=0,3,2);
  532.             wy=11;
  533.        
  534.             if(DARKLINK_CAN_SLASH && !charging)
  535.             {
  536.                 if(attackclk>10) //extended stab
  537.                     wy+=2;
  538.                 if(attackclk>=14) //retracting stab
  539.                     wy-=2;
  540.             }
  541.             else
  542.             {
  543.                 if(attackclk==DARKLINK_SWORDCHARGEFRAME)
  544.                     wy-=2;
  545.                 else if(attackclk==13)
  546.                     wy-=4;
  547.                 else if(attackclk==14)
  548.                     wy-=8;
  549.             }
  550.         }  
  551.         else if(Ghost_Dir==DIR_LEFT)
  552.         {
  553.             f=1;
  554.             wx=-11;
  555.             t++;
  556.            
  557.             if(DARKLINK_CAN_SLASH && !charging)
  558.             {
  559.                 if(attackclk>10)  //extended stab
  560.                     wx-=7;
  561.                 if(attackclk>=14) //retracting stab
  562.                     wx+=7;
  563.             }
  564.             else
  565.             {
  566.                 if(attackclk==DARKLINK_SWORDCHARGEFRAME)
  567.                     wx+=2;
  568.                 else if(attackclk==13)
  569.                     wx+=4;
  570.                 else if(attackclk==14)
  571.                     wx+=8;
  572.             }
  573.         }  
  574.         else if(Ghost_Dir==DIR_RIGHT)
  575.         {
  576.             wx=11;
  577.             t++;
  578.            
  579.             if(DARKLINK_CAN_SLASH && !charging)
  580.             {
  581.                 if(attackclk>10) //extended stab
  582.                     wx+=7;
  583.                 if(attackclk>=14) //retracting stab
  584.                     wx-=7;
  585.             }
  586.             else
  587.             {
  588.                 if(attackclk==DARKLINK_SWORDCHARGEFRAME)
  589.                     wx-=2;
  590.                 else if(attackclk==13)
  591.                     wx-=4;
  592.                 else if(attackclk==14)
  593.                     wx-=8;
  594.             }
  595.         }
  596.        
  597.         if(DARKLINK_CAN_SLASH && attackclk<11)
  598.         {
  599.             int t2=t+2; //slashing tiles
  600.             if(Ghost_Dir==DIR_UP)
  601.             {
  602.                 wx=15;
  603.                 wy=-3;
  604.                 t++;
  605.                 f=0;                                     //starts pointing right
  606.                
  607.                 if(attackclk>=7)
  608.                 {
  609.                     wy-=9;
  610.                     wx-=3;
  611.                     t=t2;
  612.                     f=0;
  613.                 }
  614.             }  
  615.             else if(Ghost_Dir==DIR_DOWN)
  616.             {
  617.                 wx=-13;
  618.                 wy=-1;
  619.                 t++;
  620.                 f=1;                                     //starts pointing left
  621.                
  622.                 if(attackclk>=7)
  623.                 {
  624.                     wy+=15;
  625.                     wx+=2;
  626.                     t=t2;
  627.                     t++;
  628.                     f=0;
  629.                 }
  630.             }
  631.             else if(Ghost_Dir==DIR_LEFT)
  632.             {
  633.                 wx=3;
  634.                 wy=-15;
  635.                 t--;
  636.                 f=0;                                     //starts pointing up
  637.            
  638.                 if(attackclk>=7)
  639.                 {
  640.                     wx-=15;
  641.                     wy+=3;
  642.                     t=t2;  
  643.                     t+=2;
  644.                     f=0;
  645.                 }
  646.             }  
  647.             if(Ghost_Dir==DIR_RIGHT)
  648.             {
  649.                 --t;
  650.            
  651.                 if(spins>0 || DARKLINK_SWORD_FLIP_FIX))
  652.                 {
  653.                     wx=1;
  654.                     wy=13;
  655.                     f=2;
  656.                 }
  657.                 else
  658.                 {
  659.                     wx=3;
  660.                     wy=-15;
  661.                     f=0;
  662.                 }
  663.            
  664.                 if(attackclk>=7)
  665.                 {
  666.                     wx+=15;
  667.                     t=t2;
  668.                    
  669.                     if(spins>0 || DARKLINK_SLASH_FLIP_FIX)
  670.                     {
  671.                         wx-=1;
  672.                         wy-=2;
  673.                     }
  674.                     else
  675.                     {
  676.                         t+=3;
  677.                         f=0;
  678.                         wy+=3;
  679.                     }
  680.                 }
  681.             }
  682.         }
  683.        
  684.         w->X = Ghost_X+wx;
  685.         w->Y = Ghost_Y+wy;;
  686.         w->Tile = t;
  687.         w->Flip = f;
  688.         w->Dir = Ghost_Dir;
  689.     }
  690.     int DLCenterX()
  691.     {
  692.         Ghost_X+(Ghost_TileWidth*8);
  693.     }
  694.     int DLCenterY()
  695.     {
  696.         Ghost_Y+(Ghost_TileHeight*8);
  697.     }
  698.     int DLDistanceTo(float dx, float dy)
  699.     {
  700.         Distance(DLCenterX,DLCenterY,dx,dy);
  701.     }
  702.     int GetComboOffset(fcc this, int cmb)
  703.     {
  704.         if(cmb<0)
  705.             return this->Misc[DARKLINK_IDX_BASE_COMBO]+(cmb*4);
  706.         else
  707.             return this->Misc[DARKLINK_IDX_BASE_COMBO]+(cmb*4)+Ghost_Dir;          
  708.     }
  709. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement