ZoriaRPG

Zaxarone: Fixed Shields

May 19th, 2017
112
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. import "std.zh"
  2. import "string.zh"
  3. import "ghost.zh"
  4. import "ffcscript.zh"
  5. import "stdextra.zh"
  6. import "laser.zh"
  7. //global constants, arrays etc, etc...
  8. const int SFX_GBSHIELD = 17; //Shield active SFX
  9.  
  10. //Arrays -Z: Needs new save for this version.
  11. int ___GRAM[1024]; //Global RAM
  12. bool Owns[256];
  13.  
  14. //Array Index Constants.
  15. const int SHIELD_BUTTON = 500; //Array Index
  16. const int SHIELD_USES_L = 1;
  17. const int SHIELD_USES_R = 2;
  18. const int SHIELD_CRRENT_ITEM = 501;
  19.  
  20.  
  21. int MooshPit[16];
  22. const int MP_LASTX = 0;
  23. const int MP_LASTY = 1;
  24. const int MP_LASTDMAP = 2;
  25. const int MP_LASTSCREEN = 3;
  26. const int MP_ENTRYX = 4;
  27. const int MP_ENTRYY = 5;
  28. const int MP_ENTRYDMAP = 6;
  29. const int MP_ENTRYSCREEN = 7;
  30. const int MP_FALLX = 8;
  31. const int MP_FALLY = 9;
  32. const int MP_FALLTIMER = 10;
  33. const int MP_FALLSTATE = 11;
  34. const int MP_DAMAGETYPE = 12;
  35.  
  36. const int CT_HOLELAVA = 128; //Combo type for pits (No Ground Enemies by default)
  37. const int CF_LAVA = 98; //Combo flag marking pits as lava (Script 1 by default)
  38.  
  39. const int SPR_FALLHOLE = 88; //Sprite for Link falling in a hole
  40. const int SPR_FALLLAVA = 89; //Sprite for Link falling in lava
  41.  
  42. const int SFX_FALLHOLE = 38; //Sound for falling in a hole
  43. const int SFX_FALLLAVA = 13; //Sound for falling in lava
  44.  
  45. const int DAMAGE_FALLHOLE = 8; //How much damage pits deal (1/2 heart default)
  46. const int DAMAGE_FALLLAVA = 16; //How much damage lava deals (1 heart default)
  47.  
  48. const int FFC_MOOSHPIT_AUTOWARPA = 32; //FFC that turns into an auto side warp combo when you fall in a pit
  49. const int CMB_MOOSHPIT_AUTOWARPA = 2; //Combo number of an invisible Auto Side Warp A combo
  50. const int SF_MISC_MOOSHPITWARP = 2; //Number of the screen flag under the Misc. section that makes pits warp (Script 1 by default)
  51.                                     //All pit warps use Side Warp A
  52.                                
  53. //Width and height of Link's hitbox for colliding with pits
  54. const int MOOSHPIT_LINKHITBOXWIDTH = 2;
  55. const int MOOSHPIT_LINKHITBOXHEIGHT = 2;
  56.  
  57. //Width and height of Link's hitbox for colliding with pits/lava in sideview
  58. const int MOOSHPIT_SIDEVIEW_LINKHITBOXWIDTH = 2;
  59. const int MOOSHPIT_SIDEVIEW_LINKHITBOXHEIGHT = 2;
  60.  
  61.  
  62. //moosh pit constsants
  63. global script Active{
  64.     void run(){
  65.     bool shieldOn;
  66.         StartGhostZH();
  67.         MooshPit_Init();
  68.        
  69.         while(true){
  70.             DoShield( CurShield() );
  71.             UpdateGhostZH1();
  72.             MooshPit_Update();
  73.             Waitdraw();
  74.             UpdateGhostZH2();
  75.             Waitframe();
  76.         }
  77.     }
  78. }
  79.  
  80. //global funtions go here
  81.  
  82.  
  83. //Sets the btton sed by the shield.
  84. void ShieldButton(int button){
  85.     ___GRAM[SHIELD_BUTTON] = button;
  86. }
  87.  
  88. //Gets crrent shield btton.
  89. int ShieldButton(){ return ___GRAM[SHIELD_BUTTON]; }
  90.  
  91. //Checks if the player is pressing a button for a shield.
  92. bool PressShield(){
  93.     if ( ( ShieldButton()== SHIELD_USES_L && Link->InputL ) || ( ShieldButton() == SHIELD_USES_R && Link->InputR ) ) { return true; }
  94.     return false;
  95. }
  96.  
  97. //Checks or sets the current shield item.
  98. int CurShield(){ return ___GRAM[SHIELD_CRRENT_ITEM]; }
  99. void CurShield(int itm){ ___GRAM[SHIELD_CRRENT_ITEM] = itm; }
  100.  
  101. //Runs shield on button press.
  102. void DoShield(int itm){
  103.     if ( PressShield() && !Link->Item[itm] ) { Link->Item[itm] = true; Game->PlaySound(SFX_GBSHIELD); }
  104.     if ( !PressShield() && Link->Item[itm] ) { Link->Item[itm] = false; Game->PlaySound(SFX_GBSHIELD); }
  105. }
  106.  
  107.  
  108. bool Owns(int itm){ return Owns[itm]; }
  109.  
  110. bool MooshPit_OnPit(int LinkX, int LinkY){
  111.     if(MooshPit_OnFFC(LinkX, LinkY)){
  112.         return false;
  113.     }
  114.    
  115.     bool sideview;
  116.     if(Screen->Flags[SF_ROOMTYPE]&100b)
  117.         sideview = true;
  118.     //wew lad
  119.     int width = MOOSHPIT_LINKHITBOXWIDTH;
  120.     int height = MOOSHPIT_LINKHITBOXHEIGHT;
  121.     for(int x=0; x<=1; x++){
  122.         for(int y=0; y<=1; y++){
  123.             int X; int Y;
  124.             if(sideview){ //Hitbox functions differently in sideview
  125.                 width = MOOSHPIT_SIDEVIEW_LINKHITBOXWIDTH;
  126.                 height = MOOSHPIT_SIDEVIEW_LINKHITBOXHEIGHT;
  127.                 X = LinkX+7-width/2+width;
  128.                 Y = LinkY+7-height/2+height;
  129.             }
  130.             else{
  131.                 X = LinkX+7-width/2+width;
  132.                 Y = LinkY+11-height/2+height;
  133.             }
  134.            
  135.             //If one corner of Link's hitbox isn't on a pit, return false
  136.             if(Screen->ComboT[ComboAt(X, Y)]!=CT_HOLELAVA){
  137.                 return false;
  138.             }
  139.         }
  140.     }
  141.     return true;
  142. }
  143.  
  144. bool MooshPit_OnFFC(int LinkX, int LinkY){
  145.     for(int i=1; i<=32; i++){ //Cycle through every FFC
  146.         ffc f = Screen->LoadFFC(i);
  147.         //Check if the FFC is solid
  148.         if(f->Data>0&&!f->Flags[FFCF_CHANGER]&&!f->Flags[FFCF_ETHEREAL]){
  149.             //Check if Link collides with the FFC
  150.             if(RectCollision(LinkX+4, LinkY+9, LinkX+11, LinkY+14, f->X, f->Y, f->X+f->EffectWidth-1, f->Y+f->EffectHeight-1)){
  151.                 return true;
  152.             }
  153.         }
  154.     }
  155.     //If Link doesn't collide with any FFC, return false
  156.     return false;
  157. }
  158.  
  159. void MooshPit_Init(){
  160.     MooshPit[MP_LASTX] = Link->X;
  161.     MooshPit[MP_LASTY] = Link->Y;
  162.     MooshPit[MP_LASTDMAP] = Game->GetCurDMap();
  163.     MooshPit[MP_LASTSCREEN] = Game->GetCurDMapScreen();
  164.     MooshPit[MP_ENTRYX] = Link->X;
  165.     MooshPit[MP_ENTRYY] = Link->Y;
  166.     MooshPit[MP_ENTRYDMAP] = Game->GetCurDMap();
  167.     MooshPit[MP_ENTRYSCREEN] = Game->GetCurDMapScreen();
  168.     MooshPit[MP_FALLSTATE] = 0;
  169.     MooshPit[MP_FALLTIMER] = 0;
  170.     Link->CollDetection = true;
  171.     Link->Invisible = false;
  172. }
  173.  
  174. void MooshPit_Update(){
  175.     bool isWarp;
  176.     if(Screen->Flags[SF_MISC]&(1<<SF_MISC_MOOSHPITWARP))
  177.         isWarp = true;
  178.    
  179.     bool sideview;
  180.     if(Screen->Flags[SF_ROOMTYPE]&100b)
  181.         sideview = true;
  182.    
  183.     if(Link->Action!=LA_SCROLLING){
  184.         //Update the entry point whenever the screen changes
  185.         if(MooshPit[MP_ENTRYDMAP]!=Game->GetCurDMap()||MooshPit[MP_ENTRYSCREEN]!=Game->GetCurDMapScreen()){
  186.             MooshPit[MP_ENTRYX] = Link->X;
  187.             MooshPit[MP_ENTRYY] = Link->Y;
  188.             MooshPit[MP_ENTRYDMAP] = Game->GetCurDMap();
  189.             MooshPit[MP_ENTRYSCREEN] = Game->GetCurDMapScreen();
  190.         }
  191.        
  192.         if(MooshPit[MP_FALLSTATE]==0){ //Not falling in pit
  193.             if(Link->Z<=0&&MooshPit_OnPit(Link->X, Link->Y)){ //If Link steps on a pit
  194.                 int underLink;
  195.                 if(!sideview)
  196.                     underLink = ComboAt(Link->X+8, Link->Y+12);
  197.                 else
  198.                     underLink = ComboAt(Link->X+8, Link->Y+8);
  199.            
  200.                 lweapon fall;
  201.                
  202.                 Link->X = ComboX(underLink);
  203.                 Link->Y = ComboY(underLink);
  204.                
  205.                 //Check if the combo is lava
  206.                 if(ComboFI(underLink, CF_LAVA)){
  207.                     //Play sound and display animation
  208.                     Game->PlaySound(SFX_FALLLAVA);
  209.                     fall = CreateLWeaponAt(LW_SCRIPT10, Link->X, Link->Y);
  210.                     fall->UseSprite(SPR_FALLLAVA);
  211.                     fall->CollDetection = false;
  212.                     fall->DeadState = fall->ASpeed*fall->NumFrames;
  213.                
  214.                     //Mark as lava damage
  215.                     MooshPit[MP_DAMAGETYPE] = 1;
  216.                 }
  217.                 //Otherwise it's a pit
  218.                 else{
  219.                     //Play sound and display animation
  220.                     Game->PlaySound(SFX_FALLHOLE);
  221.                     fall = CreateLWeaponAt(LW_SCRIPT10, Link->X, Link->Y);
  222.                     fall->UseSprite(SPR_FALLHOLE);
  223.                     fall->CollDetection = false;
  224.                     fall->DeadState = fall->ASpeed*fall->NumFrames;
  225.                
  226.                     //Mark as hole damage
  227.                     MooshPit[MP_DAMAGETYPE] = 0;
  228.                 }
  229.                
  230.                 MooshPit[MP_FALLX] = Link->X;
  231.                 MooshPit[MP_FALLY] = Link->Y;
  232.                
  233.                 //Cooldown should last as long as the fall animation
  234.                 MooshPit[MP_FALLSTATE] = 1;
  235.                 MooshPit[MP_FALLTIMER] = fall->DeadState;
  236.                
  237.                 //Render Link invisible and intangible
  238.                 Link->Invisible = true;
  239.                 Link->CollDetection = false;
  240.                
  241.                 NoAction();
  242.             }
  243.             else{ //All other times, while Link is on solid ground, record Link's last position
  244.                 if(sideview){
  245.                     //Link has no Z value in sideview, so we check if he's on a platform instead
  246.                     if(OnSidePlatform(Link->X, Link->Y)){
  247.                         MooshPit[MP_LASTDMAP] = Game->GetCurDMap();
  248.                         MooshPit[MP_LASTSCREEN] = Game->GetCurDMapScreen();
  249.                         MooshPit[MP_LASTX] = Link->X;
  250.                         MooshPit[MP_LASTY] = Link->Y;
  251.                     }
  252.                 }
  253.                 else{
  254.                     if(Link->Z<=0){
  255.                         MooshPit[MP_LASTDMAP] = Game->GetCurDMap();
  256.                         MooshPit[MP_LASTSCREEN] = Game->GetCurDMapScreen();
  257.                         MooshPit[MP_LASTX] = Link->X;
  258.                         MooshPit[MP_LASTY] = Link->Y;
  259.                     }
  260.                 }
  261.             }
  262.         }
  263.         else if(MooshPit[MP_FALLSTATE]==1){ //Falling animation
  264.             if(MooshPit[MP_FALLTIMER]>0)
  265.                 MooshPit[MP_FALLTIMER]--;
  266.        
  267.             Link->Jump = 0;
  268.             Link->Z = 0;
  269.            
  270.             //Keep Link invisible just in case
  271.             Link->Invisible = true;
  272.             Link->CollDetection = false;
  273.             NoAction();
  274.             if(MooshPit[MP_FALLTIMER]==0){
  275.                 if(!isWarp||MooshPit[MP_DAMAGETYPE]==1){ //If the pit isn't a warp, deal damage and move Link back to the return point
  276.                     //If the entry would dump Link back in the pit, dump him out at the failsafe position
  277.                     if(MooshPit_OnPit(MooshPit[MP_ENTRYX], MooshPit[MP_ENTRYY])){
  278.                         Link->X = MooshPit[MP_LASTX];
  279.                         Link->Y = MooshPit[MP_LASTY];
  280.                         //If the failsafe position was on a different screen, warp there
  281.                         if(Game->GetCurDMap()!=MooshPit[MP_LASTDMAP]||Game->GetCurDMapScreen()!=MooshPit[MP_LASTSCREEN]){
  282.                             Link->PitWarp(MooshPit[MP_LASTDMAP], MooshPit[MP_LASTSCREEN]);
  283.                         }
  284.                
  285.                         Link->Invisible = false;
  286.                         Link->CollDetection = true;
  287.                     }
  288.                     else{
  289.                         //Move Link to the start and make him visible
  290.                         Link->X = MooshPit[MP_ENTRYX];
  291.                         Link->Y = MooshPit[MP_ENTRYY];
  292.                        
  293.                         Link->Invisible = false;
  294.                         Link->CollDetection = true;
  295.                     }
  296.                    
  297.                     //Subtract HP based on damage type
  298.                     if(MooshPit[MP_DAMAGETYPE]==1)
  299.                         Link->HP -= DAMAGE_FALLLAVA;
  300.                     else
  301.                         Link->HP -= DAMAGE_FALLHOLE;
  302.                     //Play hurt sound and animation
  303.                     Link->Action = LA_GOTHURTLAND;
  304.                     Link->HitDir = -1;
  305.                     Game->PlaySound(SFX_OUCH);
  306.                    
  307.                     MooshPit[MP_FALLSTATE] = 0;
  308.                 }
  309.                 else{
  310.                     MooshPit[MP_FALLSTATE] = 2;
  311.                     MooshPit[MP_FALLTIMER] = 1;
  312.                     ffc warp = Screen->LoadFFC(FFC_MOOSHPIT_AUTOWARPA);
  313.                     warp->Data = CMB_MOOSHPIT_AUTOWARPA;
  314.                     warp->Flags[FFCF_CARRYOVER] = false;
  315.                 }
  316.             }
  317.         }
  318.         else if(MooshPit[MP_FALLSTATE]==2){ //Just warped
  319.             if(sideview){
  320.                 Link->X = MooshPit[MP_FALLX];
  321.                 Link->Y = 0;
  322.             }
  323.             else{
  324.                 Link->X = MooshPit[MP_FALLX];
  325.                 Link->Y = MooshPit[MP_FALLY];
  326.                 Link->Z = 176;
  327.             }
  328.             Link->Invisible = false;
  329.             Link->CollDetection = true;
  330.            
  331.             MooshPit[MP_FALLSTATE] = 0;
  332.             MooshPit[MP_FALLTIMER] = 0;
  333.         }
  334.     }
  335. }
  336.  
  337. //ffc scripts------------------------------------------------------------------------------------------------------------@ffcs
  338. const int RESET_NPC_LAYER_ON_ENTRY = 1; //This fix will replace all CMB_NPC_SOLID tiles with CMB_NPC_HIDDEN
  339.                                         //when entering the screen. This should prevent problems with shared
  340.                                         //layers. If you don't want this fix, set it to 0.
  341.  
  342. const int LAYER_NPC = 2; //The layer NPCs use for solid combos
  343. const int CMB_NPC_HIDDEN = 4; //Non-solid combo used for hidden NPCs
  344. const int CMB_NPC_SOLID = 1; //Solid combo placed under visible NPCs
  345.  
  346. const int LAYER_NPC_CANTALK = 4; //The layer used for the speech bubble
  347. const int CMB_NPC_CANTALK = 0; //The combo used for the speech bubble
  348. const int CS_NPC_CANTALK = 8; //The CSet used for the speech bubble
  349.  
  350. const int NPCBT_NONE = 0; //Regular NPCs
  351. const int NPCBT_FACELINK = 1; //NPCs that turn to face Link
  352. const int NPCBT_GUARDH = 2; //NPCs that move along a horizontal path
  353. const int NPCBT_GUARDV = 3; //NPCs that move along a vertical path
  354.  
  355. ffc script NPCScript{
  356.     void run(int String, int ItemCheck, int Type, int Arg1, int Arg2, int NoSolid, int Script){
  357.         //Stores the NPC's combo, hides it
  358.         int Combo = this->Data;
  359.         this->Data = CMB_NPC_HIDDEN;
  360.         //Waits until the NPC should appear and shows it
  361.         if(ItemCheck<0){
  362.             while(!Link->Item[Abs(ItemCheck)]){
  363.                 Waitframe();
  364.             }
  365.             this->Data = Combo;
  366.             if(Type==NPCBT_FACELINK){
  367.                 this->Data = Combo + Arg1;
  368.             }
  369.         }
  370.         else if(ItemCheck>0){
  371.             if(!Link->Item[Abs(ItemCheck)]){
  372.                 this->Data = Combo;
  373.                 if(Type==NPCBT_FACELINK){
  374.                     this->Data = Combo + Arg1;
  375.                 }
  376.             }
  377.         }
  378.         else if(ItemCheck==0){
  379.             this->Data = Combo;
  380.             if(Type==NPCBT_FACELINK){
  381.                 this->Data = Combo + Arg1;
  382.             }
  383.         }
  384.         //Saves the width and height of the FFC for collision checks
  385.         int Width = 16;
  386.         int Height = 16;
  387.         if(this->EffectWidth!=16)
  388.             Width = this->EffectWidth;
  389.         else if(this->TileWidth>1)
  390.             Width = this->TileWidth*16;
  391.         if(this->EffectHeight!=16)
  392.             Height = this->EffectHeight;
  393.         else if(this->TileHeight>1)
  394.             Height = this->TileHeight*16;
  395.         //Wait until the screen is done scrolling to avoid a weird ZC crashing bug
  396.         Waitframe();
  397.         while(Link->Action==LA_SCROLLING){
  398.             Waitframe();
  399.         }
  400.         //Shared Layer Fix
  401.         if(RESET_NPC_LAYER_ON_ENTRY==1){
  402.             if(Screen->LoadFFC(FindFFCRunning(this->Script))==this){
  403.                 for(int i=0; i<176; i++){
  404.                     if(GetLayerComboD(LAYER_NPC, i)==CMB_NPC_SOLID){
  405.                         SetLayerComboD(LAYER_NPC, i, CMB_NPC_HIDDEN);
  406.                     }
  407.                 }
  408.             }
  409.         }
  410.         //Sets the space below the NPC or the space a guard NPC occupies to be solid
  411.         if(LAYER_NPC>-1&&NoSolid==0){
  412.             if(Type==NPCBT_GUARDH){
  413.                 for(int x=Arg1; x<=Arg2+this->TileWidth-1; x++){
  414.                     for(int y=Floor(this->Y/16); y<=Floor(this->Y/16)+this->TileHeight-1; y++){
  415.                         SetLayerComboD(LAYER_NPC, y*16+x, CMB_NPC_SOLID);
  416.                     }
  417.                 }
  418.             }
  419.             else if(Type==NPCBT_GUARDV){
  420.                 for(int x=Floor(this->X/16); x<=Floor(this->X/16)+this->TileWidth-1; x++){
  421.                     for(int y=Arg1; y<=Arg2+this->TileHeight-1; y++){
  422.                         SetLayerComboD(LAYER_NPC, y*16+x, CMB_NPC_SOLID);
  423.                     }
  424.                 }
  425.             }
  426.             else{
  427.                 for(int x=Floor(this->X/16); x<=Floor(this->X/16)+this->TileWidth-1; x++){
  428.                     for(int y=Floor(this->Y/16); y<=Floor(this->Y/16)+this->TileHeight-1; y++){
  429.                         SetLayerComboD(LAYER_NPC, y*16+x, CMB_NPC_SOLID);
  430.                     }
  431.                 }
  432.             }
  433.         }
  434.         while(true){
  435.             //Removes NPCs if Link has the required item
  436.             if(ItemCheck>0){
  437.                 if(Link->Item[ItemCheck]){
  438.                     this->Data = CMB_NPC_HIDDEN;
  439.                     if(LAYER_NPC>-1&&NoSolid==0){
  440.                         if(Type==NPCBT_GUARDH){
  441.                             for(int x=Arg1; x<=Arg2+this->TileWidth-1; x++){
  442.                                 for(int y=Floor(this->Y/16); y<=Floor(this->Y/16)+this->TileHeight-1; y++){
  443.                                     SetLayerComboD(LAYER_NPC, y*16+x, CMB_NPC_HIDDEN);
  444.                                 }
  445.                             }
  446.                         }
  447.                         else if(Type==NPCBT_GUARDV){
  448.                             for(int x=Floor(this->X/16); x<=Floor(this->X/16)+this->TileWidth-1; x++){
  449.                                 for(int y=Arg1; y<=Arg2+this->TileHeight-1; y++){
  450.                                     SetLayerComboD(LAYER_NPC, y*16+x, CMB_NPC_HIDDEN);
  451.                                 }
  452.                             }
  453.                         }
  454.                         else{
  455.                             for(int x=Floor(this->X/16); x<=Floor(this->X/16)+this->TileWidth-1; x++){
  456.                                 for(int y=Floor(this->Y/16); y<=Floor(this->Y/16)+this->TileHeight-1; y++){
  457.                                     SetLayerComboD(LAYER_NPC, y*16+x, CMB_NPC_HIDDEN);
  458.                                 }
  459.                             }
  460.                         }
  461.                     }
  462.                     Quit();
  463.                 }
  464.             }
  465.             //Handles animation for turning NPCs
  466.             if(Type==NPCBT_FACELINK&&(Link->X>0&&Link->X<240&&Link->Y>0&&Link->Y<160)){
  467.                 if(Distance(CenterLinkX(), CenterLinkY(), CenterX(this), CenterY(this))<Arg2)
  468.                     this->Data = Combo + AngleDir4(Angle(CenterX(this), CenterY(this), CenterLinkX(), CenterLinkY()));
  469.                 else
  470.                     this->Data = Combo + Arg1;
  471.             }
  472.             //Handles movement for guard NPCs
  473.             else if(Type==NPCBT_GUARDH){
  474.                 if(Link->X>16*Arg1-32&&Link->X<16*Arg2+32&&Link->Y>this->Y-32&&Link->Y<this->Y+32){
  475.                     this->X = Clamp(this->X+(-this->X + Link->X)/4, 16*Arg1, 16*Arg2);
  476.                 }
  477.             }
  478.             else if(Type==NPCBT_GUARDV){
  479.                 if(Link->X>this->X-32&&Link->X<this->X+32&&Link->Y>16*Arg1-32&&Link->Y<16*Arg2+32){
  480.                     this->Y = Clamp(this->Y+(-this->Y + Link->Y)/4, 16*Arg1, 16*Arg2);
  481.                 }
  482.             }
  483.             //Facing Up
  484.             if(Link->Dir==DIR_UP&&Link->Y>=this->Y&&Link->Y<=this->Y+Height-8&&Link->X>=this->X-8&&Link->X<=this->X+Width-8){
  485.                 if(CMB_NPC_CANTALK>0)
  486.                     Screen->FastCombo(LAYER_NPC_CANTALK, Link->X, Link->Y-16, CMB_NPC_CANTALK, CS_NPC_CANTALK, 128);
  487.                 if(Link->PressA){
  488.                     Link->InputA = false;
  489.                     Link->PressA = false;
  490.                     Screen->Message(String);
  491.                     if(Script>0){
  492.                         RunFFCScript(Script, 0);
  493.                     }
  494.                 }
  495.             }
  496.             //Facing Down
  497.             else if(Link->Dir==DIR_DOWN&&Link->Y>=this->Y-16&&Link->Y<=this->Y+Height-16&&Link->X>=this->X-8&&Link->X<=this->X+Width-8){
  498.                 if(CMB_NPC_CANTALK>0)
  499.                     Screen->FastCombo(LAYER_NPC_CANTALK, Link->X, Link->Y-16, CMB_NPC_CANTALK, CS_NPC_CANTALK, 128);
  500.                 if(Link->PressA){
  501.                     Link->InputA = false;
  502.                     Link->PressA = false;
  503.                     Screen->Message(String);
  504.                     if(Script>0){
  505.                         RunFFCScript(Script, 0);
  506.                     }
  507.                 }
  508.             }
  509.             //Facing Left
  510.             else if(Link->Dir==DIR_LEFT&&Link->Y>=this->Y-8&&Link->Y<=this->Y+Height-8&&Link->X>=this->X&&Link->X<=this->X+Width){
  511.                 if(CMB_NPC_CANTALK>0)
  512.                     Screen->FastCombo(LAYER_NPC_CANTALK, Link->X, Link->Y-16, CMB_NPC_CANTALK, CS_NPC_CANTALK, 128);
  513.                 if(Link->PressA){
  514.                     Link->InputA = false;
  515.                     Link->PressA = false;
  516.                     Screen->Message(String);
  517.                     if(Script>0){
  518.                         RunFFCScript(Script, 0);
  519.                     }
  520.                 }
  521.             }
  522.             //Facing Right
  523.             else if(Link->Dir==DIR_RIGHT&&Link->Y>=this->Y-8&&Link->Y<=this->Y+Height-8&&Link->X>=this->X-16&&Link->X<=this->X+Width-16){
  524.                 if(CMB_NPC_CANTALK>0)
  525.                     Screen->FastCombo(LAYER_NPC_CANTALK, Link->X, Link->Y-16, CMB_NPC_CANTALK, CS_NPC_CANTALK, 128);
  526.                 if(Link->PressA){
  527.                     Link->InputA = false;
  528.                     Link->PressA = false;
  529.                     Screen->Message(String);
  530.                     if(Script>0){
  531.                         RunFFCScript(Script, 0);
  532.                     }
  533.                 }
  534.             }
  535.             Waitframe();
  536.         }
  537.     }
  538. }
  539.  
  540. ffc script NPCScript_Simple{
  541.     void run(int String, int Script, int D0, int D1, int D2, int D3, int D4, int D5){
  542.         //Saves the width and height of the FFC for collision checks
  543.         int Width = 16;
  544.         int Height = 16;
  545.         if(this->EffectWidth!=16)
  546.             Width = this->EffectWidth;
  547.         else if(this->TileWidth>1)
  548.             Width = this->TileWidth*16;
  549.         if(this->EffectHeight!=16)
  550.             Height = this->EffectHeight;
  551.         else if(this->TileHeight>1)
  552.             Height = this->TileHeight*16;
  553.         while(true){
  554.             //Facing Up
  555.             if(Link->Dir==DIR_UP&&Link->Y>=this->Y&&Link->Y<=this->Y+Height-8&&Link->X>=this->X-8&&Link->X<=this->X+Width-8){
  556.                 if(CMB_NPC_CANTALK>0)
  557.                     Screen->FastCombo(LAYER_NPC_CANTALK, Link->X, Link->Y-16, CMB_NPC_CANTALK, CS_NPC_CANTALK, 128);
  558.                 if(Link->PressA){
  559.                     Link->InputA = false;
  560.                     Link->PressA = false;
  561.                     Screen->Message(String);
  562.                     if(Script>0){
  563.                         int Args[8] = {D0, D1, D2, D3, D4, D5};
  564.                         RunFFCScript(Script, Args);
  565.                     }
  566.                 }
  567.             }
  568.             //Facing Down
  569.             else if(Link->Dir==DIR_DOWN&&Link->Y>=this->Y-16&&Link->Y<=this->Y+Height-16&&Link->X>=this->X-8&&Link->X<=this->X+Width-8){
  570.                 if(CMB_NPC_CANTALK>0)
  571.                     Screen->FastCombo(LAYER_NPC_CANTALK, Link->X, Link->Y-16, CMB_NPC_CANTALK, CS_NPC_CANTALK, 128);
  572.                 if(Link->PressA){
  573.                     Link->InputA = false;
  574.                     Link->PressA = false;
  575.                     Screen->Message(String);
  576.                     if(Script>0){
  577.                         int Args[8] = {D0, D1, D2, D3, D4, D5};
  578.                         RunFFCScript(Script, Args);
  579.                     }
  580.                 }
  581.             }
  582.             //Facing Left
  583.             else if(Link->Dir==DIR_LEFT&&Link->Y>=this->Y-8&&Link->Y<=this->Y+Height-8&&Link->X>=this->X&&Link->X<=this->X+Width){
  584.                 if(CMB_NPC_CANTALK>0)
  585.                     Screen->FastCombo(LAYER_NPC_CANTALK, Link->X, Link->Y-16, CMB_NPC_CANTALK, CS_NPC_CANTALK, 128);
  586.                 if(Link->PressA){
  587.                     Link->InputA = false;
  588.                     Link->PressA = false;
  589.                     Screen->Message(String);
  590.                     if(Script>0){
  591.                         int Args[8] = {D0, D1, D2, D3, D4, D5};
  592.                         RunFFCScript(Script, Args);
  593.                     }
  594.                 }
  595.             }
  596.             //Facing Right
  597.             else if(Link->Dir==DIR_RIGHT&&Link->Y>=this->Y-8&&Link->Y<=this->Y+Height-8&&Link->X>=this->X-16&&Link->X<=this->X+Width-16){
  598.                 if(CMB_NPC_CANTALK>0)
  599.                     Screen->FastCombo(LAYER_NPC_CANTALK, Link->X, Link->Y-16, CMB_NPC_CANTALK, CS_NPC_CANTALK, 128);
  600.                 if(Link->PressA){
  601.                     Link->InputA = false;
  602.                     Link->PressA = false;
  603.                     Screen->Message(String);
  604.                     if(Script>0){
  605.                         int Args[8] = {D0, D1, D2, D3, D4, D5};
  606.                         RunFFCScript(Script, Args);
  607.                     }
  608.                 }
  609.             }
  610.             Waitframe();
  611.         }
  612.     }
  613. }
  614.  
  615. const int D_TRADE = 0; //Screen->D value used for the trade sequence state
  616.  
  617. ffc script TradeSequence{
  618.     void run(int CheckItem, int TradeItem, int NoItemString, int HasItemString, int TradedString){
  619.         //Check if the player has already traded
  620.         if(Screen->D[D_TRADE]==0){
  621.             //If player hasn't traded and has the required item, play HasItemString, give the new item, and take the old item
  622.             if(Link->Item[CheckItem]){
  623.                 Screen->Message(HasItemString);
  624.                 WaitNoAction();
  625.                 item itm = CreateItemAt(TradeItem, Link->X, Link->Y);
  626.                 itm->Pickup = IP_HOLDUP;
  627.                 Link->Item[CheckItem] = false;
  628.                 Screen->D[D_TRADE] = 1;
  629.                 WaitNoAction();
  630.             }
  631.             //If player hasn't traded and doesn't have the required item, play NoItemString
  632.             else{
  633.                 Screen->Message(NoItemString);
  634.                 WaitNoAction();
  635.             }
  636.         }
  637.         //If the player has already traded, play TradedString
  638.         else{
  639.             Screen->Message(TradedString);
  640.             WaitNoAction();
  641.         }
  642.     }
  643. }
  644. // D0: Set this to 1 if you have a Normal Item set.
  645. // D1: Set this to 1 if you have a Special Item set.
  646. // D2: Set this to 1 if you have a Normal Chest set.
  647. // D3: Set this to 1 if you have a Locked Chest set.
  648. // D4: Set this to 1 if you have a Boss Chest set.
  649. const int COMPASS_SFX = 65;
  650. ffc script NyroxCompassBeep{
  651.      void run(int arg1, int arg2, int arg3, int arg4, int arg5){
  652.           if(GetLevelItem(LI_COMPASS)){
  653.                if(!Screen->State[ST_ITEM] && (arg1 == 1)){
  654.                     Game->PlaySound(COMPASS_SFX);
  655.                }
  656.                else if(!Screen->State[ST_SPECIALITEM]&& (arg2 == 1)){
  657.                     Game->PlaySound(COMPASS_SFX);
  658.                }
  659.                else if(!Screen->State[ST_CHEST]&& (arg3 == 1)){
  660.                     Game->PlaySound(COMPASS_SFX);
  661.                }
  662.                else if (!Screen->State[ST_LOCKEDCHEST] && (arg4 == 1)){
  663.                     Game->PlaySound(COMPASS_SFX);
  664.                }
  665.                else if(!Screen->State[ST_BOSSCHEST]&& (arg5 == 1)){
  666.                     Game->PlaySound(COMPASS_SFX);
  667.                }
  668.  
  669.           }
  670.      }
  671. }
  672.  
  673. //item scripts-----------------------------------------------------------------------------------------------------@Item
  674.  
  675. //Shield Pick-up. D0 is the message, D1 is the ID of this item.
  676. item script Zoria_Shield_Pickup{
  677.     void run(int msg, int item_id){
  678.         if ( msg > 0 ) { Screen->Message(msg); }
  679.         if ( item_id > 0 && item_id < 256 ) { Owns[item_id] = true; }
  680.         CurShield(item_id);
  681.     }
  682. }
  683.  
  684. //Modified to use new system. -Z
  685. item script gbshield{
  686.     void run ( int shield , int buttonsfx ){
  687.         CurShield(shield);
  688.         if ( ShieldButton() == SHIELD_USES_L ) { ShieldButton(SHIELD_USES_R); if ( buttonsfx > 0 ) Game->PlaySound(buttonsfx); }
  689.         else { ShieldButton(SHIELD_USES_L); if ( buttonsfx > 0 ) Game->PlaySound(buttonsfx); }
  690.     }
  691. }
  692.  
  693.  
  694. item script Message{
  695.     void run(int m){
  696.         Screen->Message(m);
  697.     }
  698. }
  699.  
  700. //enemy scirpts--------------------------------------------------------------------------------------------------@enemy
  701. //Three colors used for the lasers
  702. const int C_EZB_LASER1 = 0x77;
  703. const int C_EZB_LASER2 = 0x76;
  704. const int C_EZB_LASER3 = 0x7C;
  705.  
  706. const int SFX_EZB_TELEPORT = 66; //Sound when a boss teleports
  707. const int SFX_EZB_LASER = 37; //Sound when a laser is fired
  708.  
  709.  
  710. const int EZBF_4WAY         = 00000001b;
  711. const int EZBF_8WAY         = 00000010b;
  712. const int EZBF_FLYING       = 00000100b;
  713. const int EZBF_AQUATIC      = 00001000b;
  714. const int EZBF_NOFALL       = 00010000b;
  715. const int EZBF_EXPLODEEATH  = 00100000b;
  716. const int EZBF_FACELINK     = 01000000b;
  717. const int EZBF_UNBLOCKABLE  = 10000000b;
  718.  
  719. ffc script EZBoss{
  720.     void run(int enemyid){
  721.         int i; int j; int k; int angle; int dist; int x; int y;
  722.        
  723.         npc ghost = Ghost_InitAutoGhost(this, enemyid);
  724.        
  725.         int movementStyle = ghost->Attributes[0];
  726.         int attack1 = ghost->Attributes[1];
  727.         int attack2 = ghost->Attributes[2];
  728.         int attack3 = ghost->Attributes[3];
  729.         int special = ghost->Attributes[5];
  730.         int size = ghost->Attributes[6];
  731.         int fireSFX = ghost->Attributes[7];
  732.         int fireSPR = ghost->Attributes[8];
  733.         int flags = ghost->Attributes[9];
  734.        
  735.         int w = size&1111b;
  736.         int h = (size>>4)&1111b;
  737.         if(h==0)
  738.             h = w;
  739.         w = Clamp(w, 1, 4);
  740.         h = Clamp(h, 1, 4);
  741.            
  742.         int combo = ghost->Attributes[10];
  743.         Ghost_Transform(this, ghost, -1, -1, w, h);
  744.        
  745.         if(flags&EZBF_8WAY)
  746.             Ghost_SetFlag(GHF_8WAY);
  747.         else if(flags&EZBF_4WAY)
  748.             Ghost_SetFlag(GHF_4WAY);
  749.         if(flags&EZBF_NOFALL)
  750.             Ghost_SetFlag(GHF_NO_FALL);
  751.         if(flags&EZBF_FLYING){
  752.             Ghost_SetFlag(GHF_IGNORE_ALL_TERRAIN);
  753.             Ghost_SetFlag(GHF_FLYING_ENEMY);
  754.         }
  755.         else if(flags&EZBF_AQUATIC){
  756.             Ghost_SetFlag(GHF_WATER_ONLY);
  757.         }
  758.        
  759.         int stepCounter = -1;
  760.         int attackCooldown = ghost->Haltrate*10;
  761.         int stepAngle = Angle(CenterX(ghost), CenterY(ghost), CenterLinkX(), CenterLinkY());
  762.         int vX; int vY;
  763.        
  764.         if(movementStyle==4){
  765.             angle = Rand(360);
  766.             vX = VectorX(ghost->Step/100, angle);
  767.             vY = VectorY(ghost->Step/100, angle);
  768.         }
  769.        
  770.         while(true){
  771.             bool attackCond = false;
  772.             //Handle Movement
  773.             if(movementStyle==0){ //4 Way Halting Walk
  774.                 stepCounter = Ghost_HaltingWalk4(stepCounter, ghost->Step, ghost->Rate, ghost->Homing, ghost->Hunger, ghost->Haltrate, 48);
  775.                 if(stepCounter==16)
  776.                     attackCond = true;
  777.             }
  778.             else if(movementStyle==1){ //4 Way Constant Walk
  779.                 stepCounter = Ghost_ConstantWalk4(stepCounter, ghost->Step, ghost->Rate, ghost->Homing, ghost->Hunger);
  780.                 if(attackCooldown>0)
  781.                     attackCooldown--;
  782.                 else if(Rand(24)==0)
  783.                     attackCond = true;
  784.             }
  785.             else if(movementStyle==2){ //8 Way Constant Walk
  786.                 stepCounter = Ghost_ConstantWalk8(stepCounter, ghost->Step, ghost->Rate, ghost->Homing, ghost->Hunger);
  787.                 if(attackCooldown>0)
  788.                     attackCooldown--;
  789.                 else if(Rand(24)==0)
  790.                     attackCond = true;
  791.             }
  792.             else if(movementStyle==3){ //Homing in on Link
  793.                 if(Distance(CenterX(ghost), CenterY(ghost), CenterLinkX(), CenterLinkY())>8){
  794.                     EZB_FaceLink(this, ghost);
  795.                     Ghost_MoveAtAngle(Angle(CenterX(ghost), CenterY(ghost), CenterLinkX(), CenterLinkY()), ghost->Step/100, 0);
  796.                 }
  797.                 if(attackCooldown>0)
  798.                     attackCooldown--;
  799.                 else if(Rand(24)==0)
  800.                     attackCond = true;
  801.             }
  802.             else if(movementStyle==4){ //Wall Bounce
  803.                 Ghost_MoveXY(vX, vY, 0);
  804.                 if((vX<0&&!Ghost_CanMove(DIR_LEFT, 1, 0)) || (vX>0&&!Ghost_CanMove(DIR_RIGHT, 1, 0)))
  805.                     vX = -vX;
  806.                 if((vY<0&&!Ghost_CanMove(DIR_UP, 1, 0)) || (vY>0&&!Ghost_CanMove(DIR_DOWN, 1, 0)))
  807.                     vY = -vY;
  808.                    
  809.                 Ghost_Dir = EZB_AngleDir(this, ghost, Angle(0, 0, vX*10, vY*10));
  810.                 if(flags&EZBF_FACELINK)
  811.                     EZB_FaceLink(this, ghost);
  812.                 if(attackCooldown>0)
  813.                     attackCooldown--;
  814.                 else if(Rand(24)==0)
  815.                     attackCond = true;
  816.             }
  817.             else if(movementStyle==5){ //Periodic Reaim
  818.                 Ghost_MoveAtAngle(stepAngle, ghost->Step/100, 0);
  819.                 Ghost_Dir = EZB_AngleDir(this, ghost, stepAngle);
  820.                 if(flags&EZBF_FACELINK)
  821.                     EZB_FaceLink(this, ghost);
  822.                    
  823.                 if(attackCooldown>0)
  824.                     attackCooldown--;
  825.                 else if(Rand(24)==0)
  826.                     attackCond = true;
  827.                    
  828.                 stepCounter++;
  829.                 if(stepCounter>80&&Rand(10)==0){
  830.                     stepAngle = Angle(CenterX(ghost), CenterY(ghost), CenterLinkX(), CenterLinkY());
  831.                     stepCounter = 0;
  832.                 }
  833.             }
  834.             else if(movementStyle==6){ //Lazy chase
  835.                 float homing = ghost->Homing*0.001;
  836.                 float topSpeed = ghost->Step*0.01;
  837.                 vX = Clamp(vX+Sign(CenterLinkX()-CenterX(ghost))*homing, -topSpeed, topSpeed);
  838.                 vY = Clamp(vY+Sign(CenterLinkY()-CenterY(ghost))*homing, -topSpeed, topSpeed);
  839.                 Ghost_MoveXY(vX, vY, 0);
  840.                 if((vX<0&&!Ghost_CanMove(DIR_LEFT, 1, 0)) || (vX>0&&!Ghost_CanMove(DIR_RIGHT, 1, 0)))
  841.                     vX = -vX;
  842.                 if((vY<0&&!Ghost_CanMove(DIR_UP, 1, 0)) || (vY>0&&!Ghost_CanMove(DIR_DOWN, 1, 0)))
  843.                     vY = -vY;
  844.                    
  845.                 Ghost_Dir = EZB_AngleDir(this, ghost, Angle(0, 0, vX*10, vY*10));
  846.                 if(flags&EZBF_FACELINK)
  847.                     EZB_FaceLink(this, ghost);
  848.                 if(attackCooldown>0)
  849.                     attackCooldown--;
  850.                 else if(Rand(24)==0)
  851.                     attackCond = true;
  852.             }
  853.             else if(movementStyle==7){ //Hopping
  854.                 EZB_Waitframes(this, ghost, Choose(24, 32, 48));
  855.                 stepAngle = Angle(CenterX(ghost), CenterY(ghost), CenterLinkX(), CenterLinkY())+Rand(-30, 30);
  856.                 Game->PlaySound(SFX_JUMP);
  857.                 Ghost_Jump = 2.6;
  858.                 while(Ghost_Jump>0||Ghost_Z>0){
  859.                     Ghost_Dir = EZB_AngleDir(this, ghost, stepAngle);
  860.                     Ghost_MoveAtAngle(stepAngle, ghost->Step/100, 0);
  861.                     if(flags&EZBF_FACELINK)
  862.                         EZB_FaceLink(this, ghost);
  863.                     EZB_Waitframe(this, ghost);
  864.                 }
  865.                 if(Rand(ghost->Rate)==0)
  866.                     attackCond = true;
  867.             }
  868.             else if(movementStyle==8){ //Teleport
  869.                 EZB_Waitframes(this, ghost, Choose(32, 48, 96));
  870.                 EZB_Teleport(this, ghost);
  871.                 if(Rand(ghost->Rate)==0)
  872.                     attackCond = true;
  873.             }
  874.            
  875.             if(attackCond&&attack1){
  876.                 //Select an attack
  877.                 int attack;
  878.                 if(attack2==0)
  879.                     attack = attack1;
  880.                 else if(attack3==0)
  881.                     attack = Choose(attack1, attack2);
  882.                 else
  883.                     attack = Choose(attack1, attack2, attack3);
  884.            
  885.                 if(attack==1){ //Dash
  886.                     angle = Angle(CenterX(ghost), CenterY(ghost), CenterLinkX(), CenterLinkY());
  887.                     EZB_FaceLink(this, ghost);
  888.                     EZB_Waitframes(this, ghost, 30);
  889.                     while(EZB_CanMoveAngle(angle)){
  890.                         Ghost_MoveAtAngle(angle, 5, 0);
  891.                         EZB_Trail(this, ghost);
  892.                         EZB_Waitframe(this, ghost);
  893.                     }
  894.                 }
  895.                 else if(attack==2){ //Shoot (Directional)
  896.                     EZB_FiringAnim(this, ghost);
  897.                     EZB_Fire(this, ghost, CenterX(ghost)-8, CenterY(ghost)-8, EZB_DirAngle(Ghost_Dir), 150);
  898.                     EZB_Waitframes(this, ghost, 24);
  899.                 }
  900.                 else if(attack==3){ //Shoot (Angular)
  901.                     EZB_FaceLink(this, ghost);
  902.                     EZB_FiringAnim(this, ghost);
  903.                     EZB_Fire(this, ghost, CenterX(ghost)-8, CenterY(ghost)-8, Angle(CenterX(ghost), CenterY(ghost), CenterLinkX(), CenterLinkY()), 150);
  904.                     EZB_Waitframes(this, ghost, 24);
  905.                 }
  906.                 else if(attack==4){ //Tri Shot (Directional)
  907.                     EZB_FiringAnim(this, ghost);
  908.                     for(i=-1; i<=1; i++){
  909.                         EZB_Fire(this, ghost, CenterX(ghost)-8, CenterY(ghost)-8, EZB_DirAngle(Ghost_Dir)+30*i, 250);
  910.                     }
  911.                     EZB_Waitframes(this, ghost, 24);
  912.                 }
  913.                 else if(attack==5){ //Tri Shot (Angular)
  914.                     EZB_FaceLink(this, ghost);
  915.                     EZB_FiringAnim(this, ghost);
  916.                     for(i=-1; i<=1; i++){
  917.                         EZB_Fire(this, ghost, CenterX(ghost)-8, CenterY(ghost)-8, Angle(CenterX(ghost), CenterY(ghost), CenterLinkX(), CenterLinkY())+30*i, 250);
  918.                     }
  919.                     EZB_Waitframes(this, ghost, 24);
  920.                 }
  921.                 else if(attack==6){ //Stream (Directional)
  922.                     EZB_FiringAnim(this, ghost);
  923.                     angle = EZB_DirAngle(Ghost_Dir);
  924.                     EZB_Waitframes(this, ghost, 12);
  925.                     for(i=0; i<10; i++){
  926.                         EZB_Fire(this, ghost, CenterX(ghost)-8, CenterY(ghost)-8, angle, 350);
  927.                         EZB_Waitframes(this, ghost, 8);
  928.                     }
  929.                     EZB_Waitframes(this, ghost, 12);
  930.                 }
  931.                 else if(attack==7){ //Stream (Angular)
  932.                     EZB_FaceLink(this, ghost);
  933.                     EZB_FiringAnim(this, ghost);
  934.                     angle = Angle(CenterX(ghost), CenterY(ghost), CenterLinkX(), CenterLinkY());
  935.                     EZB_Waitframes(this, ghost, 12);
  936.                     for(i=0; i<10; i++){
  937.                         EZB_Fire(this, ghost, CenterX(ghost)-8, CenterY(ghost)-8, angle, 350);
  938.                         EZB_Waitframes(this, ghost, 8);
  939.                     }
  940.                     EZB_Waitframes(this, ghost, 12);
  941.                 }
  942.                 else if(attack==8){ //Breath (Directional)
  943.                     EZB_FiringAnim(this, ghost);
  944.                     angle = EZB_DirAngle(Ghost_Dir);
  945.                     EZB_Waitframes(this, ghost, 24);
  946.                     for(i=0; i<24; i++){
  947.                         EZB_Fire(this, ghost, CenterX(ghost)-8, CenterY(ghost)-8, angle+Rand(-30, 30), 250);
  948.                         EZB_Waitframes(this, ghost, 4);
  949.                     }
  950.                 }
  951.                 else if(attack==9){ //Breath (Angular)
  952.                     EZB_FaceLink(this, ghost);
  953.                     EZB_FiringAnim(this, ghost);
  954.                     angle = Angle(CenterX(ghost), CenterY(ghost), CenterLinkX(), CenterLinkY());
  955.                     EZB_Waitframes(this, ghost, 24);
  956.                     for(i=0; i<24; i++){
  957.                         EZB_Fire(this, ghost, CenterX(ghost)-8, CenterY(ghost)-8, angle+Rand(-30, 30), 250);
  958.                         EZB_Waitframes(this, ghost, 4);
  959.                     }
  960.                 }
  961.                 else if(attack==10){ //Sweep (Directional)
  962.                     EZB_FiringAnim(this, ghost);
  963.                     k = Choose(-1, 1);
  964.                     angle = EZB_DirAngle(Ghost_Dir)-45*k;
  965.                     for(i=0; i<18; i++){
  966.                         EZB_Fire(this, ghost, CenterX(ghost)-8, CenterY(ghost)-8, angle, 250);
  967.                         angle += k*5;
  968.                         EZB_Waitframes(this, ghost, 2);
  969.                     }
  970.                 }
  971.                 else if(attack==11){ //Sweep (Angular)
  972.                     EZB_FaceLink(this, ghost);
  973.                     EZB_FiringAnim(this, ghost);
  974.                     k = Choose(-1, 1);
  975.                     angle = Angle(CenterX(ghost), CenterY(ghost), CenterLinkX(), CenterLinkY())-45*k;
  976.                     for(i=0; i<18; i++){
  977.                         EZB_Fire(this, ghost, CenterX(ghost)-8, CenterY(ghost)-8, angle, 250);
  978.                         angle += k*5;
  979.                         EZB_Waitframes(this, ghost, 2);
  980.                     }
  981.                 }
  982.                 else if(attack==12){ //Bullet Barrage
  983.                     EZB_FaceLink(this, ghost);
  984.                     EZB_FiringAnim(this, ghost);
  985.                     angle = Angle(CenterX(ghost), CenterY(ghost), CenterLinkX(), CenterLinkY())-45*k;
  986.                     for(i=0; i<3; i++){
  987.                         for(j=-4; j<=4; j+=2){
  988.                             EZB_Fire(this, ghost, CenterX(ghost)-8, CenterY(ghost)-8, angle+16*j, 150);
  989.                         }
  990.                         EZB_Waitframes(this, ghost, 16);
  991.                         for(j=-5; j<=5; j+=2){
  992.                             EZB_Fire(this, ghost, CenterX(ghost)-8, CenterY(ghost)-8, angle+16*j, 150);
  993.                         }
  994.                         EZB_Waitframes(this, ghost, 24);
  995.                     }
  996.                     EZB_Waitframes(this, ghost, 24);
  997.                 }
  998.                 else if(attack==13){ //Bullet swirl
  999.                     EZB_FaceLink(this, ghost);
  1000.                     EZB_FiringAnim(this, ghost);
  1001.                     k = Choose(-1, 1);
  1002.                     angle = Rand(360);
  1003.                     for(i=0; i<20; i++){
  1004.                         for(j=0; j<5; j++){
  1005.                             EZB_Fire(this, ghost, CenterX(ghost)-8, CenterY(ghost)-8, angle+72*j, 150);
  1006.                         }
  1007.                         angle += 4*k;
  1008.                         EZB_Waitframes(this, ghost, 4);
  1009.                     }
  1010.                     EZB_Waitframes(this, ghost, 24);
  1011.                 }
  1012.                 else if(attack==14){ //Random bullet burst
  1013.                     EZB_FaceLink(this, ghost);
  1014.                     EZB_FiringAnim(this, ghost);
  1015.                     for(i=0; i<40; i++){
  1016.                         EZB_Fire(this, ghost, CenterX(ghost)-8, CenterY(ghost)-8, Rand(360), 250);
  1017.                         EZB_Waitframes(this, ghost, 2);
  1018.                     }
  1019.                     EZB_Waitframes(this, ghost, 24);
  1020.                 }
  1021.                 else if(attack==15){ //Laser
  1022.                     EZB_FaceLink(this, ghost);
  1023.                     EZB_FiringAnim(this, ghost);
  1024.                     angle = Angle(CenterX(ghost), CenterY(ghost), CenterLinkX(), CenterLinkY());
  1025.                     for(i=0; i<30; i++){
  1026.                         if(i%4<2){
  1027.                             DrawLaser(4, CenterX(ghost), CenterY(ghost), 8, angle, C_EZB_LASER3);
  1028.                         }
  1029.                         EZB_Waitframe(this, ghost);
  1030.                     }
  1031.                     Game->PlaySound(SFX_EZB_LASER);
  1032.                     for(i=0; i<20; i++){
  1033.                         Laser3Color(4, CenterX(ghost), CenterY(ghost), 8, angle, ghost->WeaponDamage, C_EZB_LASER1, C_EZB_LASER2, C_EZB_LASER3);
  1034.                         EZB_Waitframe(this, ghost);
  1035.                     }
  1036.                 }
  1037.                 else if(attack==16){ //Big Laser
  1038.                     EZB_FaceLink(this, ghost);
  1039.                     EZB_FiringAnim(this, ghost);
  1040.                     angle = Angle(CenterX(ghost), CenterY(ghost), CenterLinkX(), CenterLinkY());
  1041.                     for(i=0; i<60; i++){
  1042.                         if(i%4<2){
  1043.                             DrawLaser(4, CenterX(ghost), CenterY(ghost), 40, angle, C_EZB_LASER3);
  1044.                         }
  1045.                         EZB_Waitframe(this, ghost);
  1046.                     }
  1047.                     Game->PlaySound(SFX_EZB_LASER);
  1048.                     for(i=0; i<40; i++){
  1049.                         Laser3Color(4, CenterX(ghost), CenterY(ghost), 40, angle, ghost->WeaponDamage*2, C_EZB_LASER1, C_EZB_LASER2, C_EZB_LASER3);
  1050.                         EZB_Waitframe(this, ghost);
  1051.                     }
  1052.                 }
  1053.                 else if(attack==17){ //Laser Spread
  1054.                     EZB_FaceLink(this, ghost);
  1055.                     EZB_FiringAnim(this, ghost);
  1056.                     angle = Angle(CenterX(ghost), CenterY(ghost), CenterLinkX(), CenterLinkY());
  1057.                     for(i=0; i<30; i++){
  1058.                         for(j=-2; j<=2; j++){
  1059.                             if(i%4<2){
  1060.                                 DrawLaser(4, CenterX(ghost), CenterY(ghost), 6, angle+30*j, C_EZB_LASER3);
  1061.                             }
  1062.                         }
  1063.                         EZB_Waitframe(this, ghost);
  1064.                     }
  1065.                     Game->PlaySound(SFX_EZB_LASER);
  1066.                     for(i=0; i<20; i++){
  1067.                         for(j=-2; j<=2; j++){
  1068.                             Laser3Color(4, CenterX(ghost), CenterY(ghost), 6, angle+30*j, ghost->WeaponDamage, C_EZB_LASER1, C_EZB_LASER2, C_EZB_LASER3);
  1069.                         }
  1070.                         EZB_Waitframe(this, ghost);
  1071.                     }
  1072.                 }
  1073.                 else if(attack==18){ //Laser Spin
  1074.                     EZB_FaceLink(this, ghost);
  1075.                     EZB_FiringAnim(this, ghost);
  1076.                     k = Choose(-1, 1);
  1077.                     angle = Angle(CenterX(ghost), CenterY(ghost), CenterLinkX(), CenterLinkY())+45;
  1078.                     Game->PlaySound(SFX_EZB_LASER);
  1079.                     for(i=0; i<30; i++){
  1080.                         for(j=0; j<4; j++){
  1081.                             Laser3Color(4, CenterX(ghost), CenterY(ghost), 6, angle+90*j, ghost->WeaponDamage, C_EZB_LASER1, C_EZB_LASER2, C_EZB_LASER3);
  1082.                         }
  1083.                         EZB_Waitframe(this, ghost);
  1084.                     }
  1085.                     for(i=0; i<30; i++){
  1086.                         for(j=0; j<4; j++){
  1087.                             Laser3Color(4, CenterX(ghost), CenterY(ghost), 6, angle+90*j, ghost->WeaponDamage, C_EZB_LASER1, C_EZB_LASER2, C_EZB_LASER3);
  1088.                         }
  1089.                         angle += k;
  1090.                         EZB_Waitframe(this, ghost);
  1091.                     }
  1092.                     for(i=0; i<120; i++){
  1093.                         for(j=0; j<4; j++){
  1094.                             Laser3Color(4, CenterX(ghost), CenterY(ghost), 6, angle+90*j, ghost->WeaponDamage, C_EZB_LASER1, C_EZB_LASER2, C_EZB_LASER3);
  1095.                         }
  1096.                         angle += k*1.5;
  1097.                         EZB_Waitframe(this, ghost);
  1098.                     }
  1099.                     for(i=0; i<30; i++){
  1100.                         for(j=0; j<4; j++){
  1101.                             Laser3Color(4, CenterX(ghost), CenterY(ghost), 6, angle+90*j, ghost->WeaponDamage, C_EZB_LASER1, C_EZB_LASER2, C_EZB_LASER3);
  1102.                         }
  1103.                         angle += k;
  1104.                         EZB_Waitframe(this, ghost);
  1105.                     }
  1106.                 }
  1107.                
  1108.                
  1109.                 Ghost_Data = combo;
  1110.                
  1111.                 attackCooldown = ghost->Haltrate*10;
  1112.                 if(movementStyle==4){ //Wall bounce
  1113.                     angle = Rand(360);
  1114.                     vX = VectorX(ghost->Step/100, angle);
  1115.                     vY = VectorY(ghost->Step/100, angle);
  1116.                 }
  1117.             }
  1118.             EZB_Waitframe(this, ghost);
  1119.         }
  1120.     }
  1121.     bool EZB_CanMoveAngle(int angle){
  1122.         int vx = VectorX(10, angle);
  1123.         int vy = VectorY(10, angle);
  1124.         if((vx<0&&!Ghost_CanMove(DIR_LEFT, 1, 0))||(vx>0&&!Ghost_CanMove(DIR_RIGHT, 1, 0)))
  1125.             return false;
  1126.         if((vy<0&&!Ghost_CanMove(DIR_UP, 1, 0))||(vy>0&&!Ghost_CanMove(DIR_DOWN, 1, 0)))
  1127.             return false;
  1128.         return true;
  1129.     }
  1130.     void EZB_FiringAnim(ffc this, npc ghost){
  1131.         int flags = ghost->Attributes[9];
  1132.         int combo = ghost->Attributes[10];
  1133.         if(flags&EZBF_8WAY)
  1134.             Ghost_Data = combo+8;
  1135.         else if(flags&EZBF_4WAY)
  1136.             Ghost_Data = combo+4;
  1137.         else
  1138.             Ghost_Data = combo+1;
  1139.     }
  1140.     void EZB_Trail(ffc this, npc ghost){
  1141.         int flags = ghost->Attributes[9];
  1142.         int tile = Game->ComboTile(Ghost_Data);
  1143.         if(flags&EZBF_4WAY||flags&EZBF_8WAY)
  1144.             tile = Game->ComboTile(Ghost_Data+Ghost_Dir);
  1145.         lweapon trail = CreateLWeaponAt(LW_SCRIPT10, ghost->X+ghost->DrawXOffset, ghost->Y+ghost->DrawYOffset);
  1146.         trail->Extend = 3;
  1147.         trail->TileWidth = ghost->TileWidth;
  1148.         trail->TileHeight = ghost->TileHeight;
  1149.         trail->DrawYOffset = 0;
  1150.         trail->CSet = this->CSet;
  1151.         trail->Tile = tile;
  1152.         trail->OriginalTile = tile;
  1153.         trail->DrawStyle = DS_PHANTOM;
  1154.         trail->DeadState = 8;
  1155.     }
  1156.     int EZB_DirAngle(int dir){
  1157.         if(dir==DIR_UP)
  1158.             return -90;
  1159.         else if(dir==DIR_DOWN)
  1160.             return 90;
  1161.         else if(dir==DIR_LEFT)
  1162.             return 180;
  1163.         else if(dir==DIR_LEFTUP)
  1164.             return -135;
  1165.         else if(dir==DIR_RIGHTUP)
  1166.             return -45;
  1167.         else if(dir==DIR_LEFTDOWN)
  1168.             return 135;
  1169.         else if(dir==DIR_RIGHTDOWN)
  1170.             return 45;
  1171.         else
  1172.             return 0;
  1173.     }
  1174.     eweapon EZB_Fire(ffc this, npc ghost, int x, int y, int angle, int step){
  1175.         int flags = ghost->Attributes[9];
  1176.         int type = WeaponTypeToID(ghost->Weapon);
  1177.         int wflags;
  1178.         if(flags&EZBF_UNBLOCKABLE)
  1179.             wflags |= EWF_UNBLOCKABLE;
  1180.         if(type==EW_BEAM||type==EW_ARROW||type==EW_MAGIC||type==EW_BOMB||type==EW_SBOMB)
  1181.             wflags |= EWF_ROTATE;
  1182.            
  1183.         int fireSFX = ghost->Attributes[7];
  1184.         int fireSPR = ghost->Attributes[8];
  1185.         int sfx = fireSFX;
  1186.         if(fireSFX<=0)
  1187.             sfx = -1;
  1188.         int spr = fireSPR;
  1189.         if(fireSPR<=0)
  1190.             spr = -1;
  1191.            
  1192.         eweapon e = FireEWeapon(type, x, y, DegtoRad(angle), step, ghost->WeaponDamage, spr, sfx, wflags);
  1193.         return e;
  1194.     }
  1195.     void EZB_Teleport(ffc this, npc ghost){
  1196.         int size = ghost->Attributes[6];
  1197.         int w = size&1111b;
  1198.         int h = (size>>4)&1111b;
  1199.         if(h==0)
  1200.             h = w;
  1201.         w = Clamp(w, 1, 4);
  1202.         h = Clamp(h, 1, 4);
  1203.        
  1204.         Game->PlaySound(SFX_EZB_TELEPORT);
  1205.         int tc;
  1206.         ghost->CollDetection = false;
  1207.         for(int i=0; i<16; i++){
  1208.             if(i%2==0)
  1209.                 ghost->DrawYOffset = -1000;
  1210.             else
  1211.                 ghost->DrawYOffset = -2;
  1212.             EZB_Waitframe(this, ghost);
  1213.         }
  1214.         ghost->DrawYOffset = -1000;
  1215.         tc = Rand(176);
  1216.         for(int i=0; i<352&&(!EZB_CanPlace(this, ghost, ComboX(tc), ComboY(tc))||Distance(ComboX(tc)+ghost->HitWidth/2, ComboY(tc)+ghost->HitHeight/2, CenterLinkX(), CenterLinkY())<((w+h)/2)*8+32); i++){
  1217.             if(i>=176)
  1218.                 tc = i-176;
  1219.             else
  1220.                 tc = Rand(176);
  1221.         }
  1222.         Ghost_X = ComboX(tc);
  1223.         Ghost_Y = ComboY(tc);
  1224.         EZB_Waitframe(this, ghost);
  1225.         EZB_FaceLink(this, ghost);
  1226.         for(int i=0; i<16; i++){
  1227.             if(i%2==0)
  1228.                 ghost->DrawYOffset = -1000;
  1229.             else
  1230.                 ghost->DrawYOffset = -2;
  1231.             EZB_Waitframe(this, ghost);
  1232.         }
  1233.         ghost->DrawYOffset = -2;
  1234.         ghost->CollDetection = true;
  1235.     }  
  1236.     int EZB_AngleDir(ffc this, npc ghost, int angle){
  1237.         int flags = ghost->Attributes[9];
  1238.         if(flags&EZBF_8WAY)
  1239.             return AngleDir8(angle);
  1240.         else
  1241.             return AngleDir4(angle);
  1242.     }
  1243.     void EZB_FaceLink(ffc this, npc ghost){
  1244.         int flags = ghost->Attributes[9];
  1245.         if(flags&EZBF_8WAY)
  1246.             Ghost_Dir = AngleDir8(Angle(CenterX(ghost), CenterY(ghost), CenterLinkX(), CenterLinkY()));
  1247.         else
  1248.             Ghost_Dir = AngleDir4(Angle(CenterX(ghost), CenterY(ghost), CenterLinkX(), CenterLinkY()));
  1249.     }
  1250.     bool EZB_CanPlace(ffc this, npc ghost, int X, int Y){
  1251.         for(int x=ghost->HitXOffset; x<=ghost->HitXOffset+ghost->HitWidth-1; x=Min(x+8, ghost->HitXOffset+ghost->HitWidth-1)){
  1252.             for(int y=ghost->HitYOffset; y<=ghost->HitYOffset+ghost->HitHeight-1; y=Min(y+8, ghost->HitYOffset+ghost->HitHeight-1)){
  1253.                 if(!Ghost_CanMovePixel(X+x, Y+y))
  1254.                     return false;
  1255.                 if(y==ghost->HitYOffset+ghost->HitHeight-1)
  1256.                     break;
  1257.             }
  1258.             if(x==ghost->HitXOffset+ghost->HitWidth-1)
  1259.                 break;
  1260.         }
  1261.         return true;
  1262.     }
  1263.     void EZB_Waitframes(ffc this, npc ghost, int frames){
  1264.         for(int i=0; i<frames; i++){
  1265.             EZB_Waitframe(this, ghost);
  1266.         }
  1267.     }
  1268.     void EZB_Waitframe(ffc this, npc ghost){
  1269.         int flags = ghost->Attributes[9];
  1270.         if(flags&EZBF_EXPLODEEATH)
  1271.             Ghost_Waitframe(this, ghost, 1, true);
  1272.         else
  1273.             Ghost_Waitframe(this, ghost);
  1274.     }
  1275. }
  1276.  
  1277.  
  1278. ffc script gbmold
  1279. {
  1280.     void run(int enemyID)
  1281.     {
  1282.         npc ghost = Ghost_InitAutoGhost(this, enemyID);
  1283.         Ghost_SetFlag(GHF_FULL_TILE_MOVEMENT);
  1284.         Ghost_SetFlag(GHF_REDUCED_KNOCKBACK);
  1285.         npc segment[2];
  1286.         int Xtrack[160];
  1287.         int Ytrack[160];
  1288.         int vars [16] = {Xtrack,Ytrack};
  1289.         for(int i=0;i<2;i++)
  1290.             {
  1291.                 segment[i] = CreateNPCAt(NPC_ENEMYFIRE,Ghost_X,Ghost_Y);
  1292.                 Ghost_SetAllDefenses(segment[i],NPCDT_IGNORE);
  1293.                 segment[i]->DrawYOffset = -1000;
  1294.                 segment[i]->Damage= ghost->Damage;
  1295.             }
  1296.         for(int i=0; i<SizeOfArray(Xtrack); i++)
  1297.             {
  1298.                 Xtrack[i] = Ghost_X;
  1299.                 Ytrack[i] = Ghost_Y;
  1300.             }
  1301.             int angle = Rand(600);
  1302.             int turndir = Choose(-1,0,1);
  1303.             int turncounter = Choose(-1,0,1);
  1304.             ghost->DrawYOffset = -1000;
  1305.         while (true)
  1306.         {
  1307.             angle = WrapDegrees(angle+turndir*4);
  1308.             Ghost_Dir = AngleDir8(angle);
  1309.             Ghost_MoveAtAngle(angle, ghost->Step/100, 0);
  1310.             if(turncounter>0)
  1311.                 turncounter--;
  1312.             else
  1313.                 turndir = Choose(-1, 0, 1);
  1314.             int vx = VectorX(10, angle);
  1315.             int vy = VectorY(10, angle);
  1316.             if((vx<0&&!Ghost_CanMove(DIR_LEFT, 1, 0))||(vx>0&&!Ghost_CanMove(DIR_RIGHT, 1, 0))){
  1317.                 vx = -vx;
  1318.             }
  1319.             if((vy<0&&!Ghost_CanMove(DIR_UP, 1, 0))||(vy>0&&!Ghost_CanMove(DIR_DOWN, 1, 0))){
  1320.                 vy = -vy;
  1321.             }
  1322.             angle = Angle(0, 0, vx, vy);
  1323.             Mold_Waitframe(this, ghost, segment, vars);
  1324.         }
  1325.         Mold_Waitframe(this,ghost,segment,vars);
  1326.     }
  1327.  
  1328.     void Mold_Waitframe(ffc this, npc ghost,npc segment,int vars)
  1329.     {
  1330.         Mold_UpdateTrack(vars);
  1331.         Mold_Draw(this,ghost,segment,vars);
  1332.         if(!Ghost_Waitframe(this, ghost, false, false))
  1333.         {
  1334.             ghost->DrawYOffset = -2;
  1335.             Mold_UpdateTrack(vars);
  1336.             Mold_Draw(this, ghost, segment,vars);
  1337.             Ghost_Waitframe(this, ghost);
  1338.            
  1339.         }
  1340.     }
  1341.  
  1342.     void Mold_UpdateTrack(int vars)
  1343.     {
  1344.     int Xtrack=vars[0];
  1345.     int Ytrack=vars[1];
  1346.         for(int i=SizeOfArray(Xtrack)-1;i>=1;i--)
  1347.         {
  1348.             Xtrack[i] = Xtrack[i-1];
  1349.             Ytrack[i] = Ytrack[i-1];
  1350.         }
  1351.             Xtrack[0] = Ghost_X;
  1352.             Ytrack[0] = Ghost_Y;
  1353.     }
  1354.     void Mold_Draw(ffc this,npc ghost, npc segment, int vars)
  1355.     {
  1356.         int Xtrack=vars[0];
  1357.         int Ytrack=vars[1];
  1358.         int combo = ghost->Attributes[10];
  1359.         for (int i=1; i>=0; i--)
  1360.         {
  1361.             if(segment[i]->isValid())
  1362.             {
  1363.                    
  1364.                 if(ghost->HP<=0)
  1365.                 {
  1366.                     segment[i]->HP=-1000;
  1367.                 }
  1368.                
  1369.                 else
  1370.                 {
  1371.                     int spacing = 10;
  1372.                     int x = Xtrack[spacing+spacing*i];
  1373.                     int y = Ytrack[spacing+spacing*i];
  1374.                     segment[i]->X = x;
  1375.                     segment[i]->Y = y;
  1376.                     Screen->FastCombo(2,x,y,combo+8+i,this->CSet,128);
  1377.                 }
  1378.             }
  1379.         }
  1380.         //ghost->DrawYOffset = -1000;
  1381.         Screen->FastCombo(2,Ghost_X,Ghost_Y,combo+Ghost_Dir, this->CSet,128);
  1382.     }  
  1383. }
RAW Paste Data

Adblocker detected! Please consider disabling it...

We've detected AdBlock Plus or some other adblocking software preventing Pastebin.com from fully loading.

We don't have any obnoxious sound, or popup ads, we actively block these annoying types of ads!

Please add Pastebin.com to your ad blocker whitelist or disable your adblocking software.

×