Advertisement
Guest User

DarkLink

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