Advertisement
ZoriaRPG

Z3 items

Nov 22nd, 2016
214
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 24.01 KB | None | 0 0
  1. ///////////////////////
  2. /// Z3 Magic Mirror ///
  3. /// v0.3.5          ///
  4. /// 22-Nov-2016     ///
  5. /// By: ZoriaRPG    ///
  6. ///////////////////////////////////////
  7. /// Partial Rewrite of the Original ///
  8. /// WarpFunctions.zh b1.1 from 2014 ///
  9. /// originally made by request for  ///
  10. /// Obderhode and used in the quest ///
  11. /// 'The Three Whistles'            ///
  12. ///////////////////////////////////////
  13.  
  14. //! To-Do
  15. //! Add in freeze flags and ghost suspension
  16.  
  17.  //! BUG    If Link is warped onto an entrance/exit (cave walk down/u) warp tile, that tile will activate and he will
  18.  //!        seem to walk in and out of a place then error out and return.
  19.  
  20.  //v0.3x Changelog
  21.  //v0.3.3 Modified the solidity tests for a far more fine tuned check.
  22.  //v0.3.4 Added a check to error if the player tries to use the mirron when standing on a cave combo, to prevent
  23.  // warping onto an aligning cave combo in the light world.
  24.  //0.3.5 Trimmed the solidity check slightly.
  25.  
  26. /// Global Array
  27. int Mirror[214747];
  28.  
  29. const int TEST_MIRROR_SPARKLE = 0;
  30. const int MIRROR_SPARKLE_BEFORE_WAITDRAW = 0;
  31.  
  32. //Moon Pearl Goodies
  33. const int I_MIRROR = 160;
  34. const int I_MOONPEARL = 200;
  35. const int I_BUNNYRING = 201; //A wisp ring twith a LTM for Bunny Sprites
  36.  
  37. //Options
  38. const int WARP_RETURNS_ON_INJURY        = 1;
  39. const int REQUIRE_MOON_PEARL            = 1;
  40. const int MIRROR_RETURNS_TO_DUNGEON_ENTRANCE    = 1; //This requires placing a warp return square on dungeon entrance screens.
  41.  
  42. const int MIRROR_POST_WARP_TIMER_NUM_FRAMES = 75; // Number of frames afer warping, before Link may use a warp return sparkle.
  43.  
  44. const int POST_WARP_LINK_IS_INVINCIBLE      = 0;     //If se tto '1', Link->CollDetection will be disabled for a number of
  45.                         //frames equal to:
  46.  
  47. const int WARP_INVULNERABILITY_FRAMES       = 90; //Number of frames that Link is invulnerable after warping.
  48.  
  49. //!! Caution: This may conflict with other items that grant invulnerability!
  50.  
  51.  
  52. ///Constants for Array Indices of Mirror[]
  53.  
  54. const int IS_WARPING        = 0;
  55. const int AFTER_WARP        = 1;
  56. const int RETURN_WARP       = 2;
  57. const int AFTER_RETURN_WARP     = 3;
  58.  
  59. const int WARP_SPARKLE          = 10;
  60. const int WARP_SPARKLE_DMAP         = 11;
  61. const int WARP_SPARKLE_SCREEN       = 12;
  62. const int WARP_SPARKLE_X        = 13;
  63. const int WARP_SPARKLE_Y        = 14;
  64. const int WARP_SPARKLE_RETURN_DMAP  = 15;
  65.  
  66. const int WARP_LINK_X           = 20;
  67. const int WARP_LINK_Y           = 21;
  68. const int WARP_LINK_Z           = 22;
  69. const int WARP_LINK_HP          = 23;
  70. const int WARP_LINK_TEMP_INVULNERABILITY = 24;
  71.  
  72. const int MIRROR_SPARKLE_COMBO_FRAME = 30; //Mirror array index
  73. const int MIRROR_POST_WARP_TIMER = 40;
  74.  
  75.  
  76.  
  77. //Settings
  78.  
  79. //Sounds
  80. const int SFX_WARP_ERROR    = 67;
  81. const int SFX_WARP      = 73;
  82. const int SFX_WARP_DUNGEON  = 16;
  83.  
  84. const int WARP_WAVE_DUR     = 100; //Duration of warp wavy animation (overworld)
  85. const int WARP_WAVE_DUR_DUNGEON = 100; //Duration of warp wavy animation (inside dungeons)
  86.  
  87. const int WARP_DUR      = 60;
  88. const int POST_WARP_DELAY   = 15;
  89.  
  90.  
  91.  
  92. //Mirror Sparkle Settings
  93. const int MIRROR_SPARKLE_COMBO      = 32596; // COmbo of sparkle or other warp return effect.
  94. const int MIRROR_SPARKLE_COMBO_LAYER    = 2;
  95. const int MIRROR_SPARKLE_COMBO_W    = 1;
  96. const int MIRROR_SPARKLE_COMBO_H    = 1;
  97. const int MIRROR_SPARKLE_COMBO_CSET     = 0;
  98. const int MIRROR_SPARKLE_COMBO_XSCALE   = -1;
  99. const int MIRROR_SPARKLE_COMBO_YSCALE   = -1;
  100. const int MIRROR_SPARKLE_COMBO_RX   = 0;
  101. const int MIRROR_SPARKLE_COMBO_RY   = 0;
  102. const int MIRROR_SPARKLE_COMBO_RANGLE   = 0;
  103.  
  104. const int MIRROR_SPARKLE_COMBO_FLIP     = 0;
  105. const int MIRROR_SPARKLE_COMBO_OPACITY  = 64;
  106.  
  107. const int MIRROR_SPARKLE_COMBO_NUM_FRAMES = 4;
  108. const int MIRROR_SPARKLE_COMBO_INIT_FRAME = 1;
  109.  
  110.  
  111.  
  112.  
  113. //Accessors
  114. int IsWarping(){ return Mirror[IS_WARPING]; }
  115. void IsWarping(bool state){ if ( state ) Mirror[IS_WARPING] = 1; else Mirror[IS_WARPING] = 0; }
  116.  
  117. int AfterWarp(){ return Mirror[AFTER_WARP]; }
  118. void AfterWarp(bool state){ if ( state ) Mirror[AFTER_WARP] = 1; else Mirror[AFTER_WARP] = 0; }
  119.  
  120. int IsReturnWarping(){ return Mirror[RETURN_WARP]; }
  121. void IsReturnWarping(bool state){ if ( state ) Mirror[RETURN_WARP] = 1; else Mirror[RETURN_WARP] = 0; }
  122.  
  123. int AfterReturnWarp(){ return Mirror[AFTER_RETURN_WARP]; }
  124. void AfterReturnWarp(bool state){ if ( state ) Mirror[AFTER_RETURN_WARP] = 1; else Mirror[AFTER_RETURN_WARP] = 0; }
  125.  
  126. int WarpSparkle(){ return Mirror[WARP_SPARKLE]; }
  127. void WarpSparkle(bool state){ if ( state ) Mirror[WARP_SPARKLE] = 1; else Mirror[WARP_SPARKLE] = 0; }
  128.  
  129. int WarpSparkleReturn(){ return Mirror[WARP_SPARKLE_RETURN_DMAP]; }
  130. void WarpSparkleReturn(int dmap){ Mirror[WARP_SPARKLE_RETURN_DMAP] = dmap; }
  131.  
  132. int WarpSparkleDMap(){ return Mirror[WARP_SPARKLE_DMAP]; }
  133. void WarpSparkleDMap(int dmap){ Mirror[WARP_SPARKLE_DMAP] = dmap; }
  134.  
  135. int WarpSparkleX(){ return Mirror[WARP_SPARKLE_X]; }
  136. void WarpSparkleX(int x){ Mirror[WARP_SPARKLE_X] = x; }
  137.  
  138. int WarpSparkleY(){ return Mirror[WARP_SPARKLE_Y]; }
  139. void WarpSparkleY(int y){ Mirror[WARP_SPARKLE_Y] = y; }
  140.  
  141. int WarpSparkleScreen(){ return Mirror[WARP_SPARKLE_SCREEN]; }
  142. void WarpSparkleScreen(int screen){ Mirror[WARP_SPARKLE_SCREEN] = screen; }
  143.  
  144. //The following four functions are used to manipulate,a nd check the post-warp timer,
  145. //that prevents Link from being sent back by a sparkle as soon as he finishes warping.
  146.  
  147. int WarpReturnWait(){ return Mirror[MIRROR_POST_WARP_TIMER]; }
  148. void ReducePostWarpTimer(){ if ( Mirror[MIRROR_POST_WARP_TIMER] > 0 ) Mirror[MIRROR_POST_WARP_TIMER]--; }
  149. void SetPostWarpTimer(){ Mirror[MIRROR_POST_WARP_TIMER] = MIRROR_POST_WARP_TIMER_NUM_FRAMES; }
  150. void ClearPostWarpTimer(){ Mirror[MIRROR_POST_WARP_TIMER] = 0; }
  151.  
  152.  
  153. //Functions
  154.  
  155. //Checks the present DMap and returns irts counterpart.
  156. //!! You must set up the arrays inside this function, for it to work.
  157. int GetOtherworldlyDMap(int dmap){
  158.     int q[4];
  159.     int LightWorldDMaps[]={3,-1,-1,-1,-1}; //Populate these two arrays with the IDs of your light and dark world dmaps
  160.     int DarkWorldDMaps[]={8,-1,-1,-1,-1}; //in matched pairs.
  161.     for ( q[0] = 0; q[0] < SizeOfArray(LightWorldDMaps); q[0]++ ) {
  162.         q[1] = LightWorldDMaps[ q[0] ];
  163.         q[2] = DarkWorldDMaps[ q[0] ];
  164.         if ( dmap == q[1] ) return DarkWorldDMaps[ q[0] ];
  165.         if ( dmap == q[2] ) return LightWorldDMaps[ q[0] ];
  166.     }
  167.     return -1;
  168. }
  169.  
  170. //Returns if the present dmap is a dark world dmap
  171. //!! You must set up the arrays inside this function, for it to work.
  172. bool IsDarkWorld(){
  173.     int DarkWorldDMaps[]={8,-1,-1,-1,-1};
  174.     for ( int q = 0; q < SizeOfArray(DarkWorldDMaps); q++ ) {
  175.         if ( Game->GetCurDMap() == DarkWorldDMaps[q] ) return true;
  176.     }
  177.     return false;
  178. }
  179.  
  180. //Generates coordinates for the warp return sparkle.
  181. //this is set when we use the mirror.
  182. void SetWarpReturn(){
  183.     WarpSparkle(true);
  184.     WarpSparkleX(Link->X);
  185.     WarpSparkleY(Link->Y);
  186.     WarpSparkleDMap( GetOtherworldlyDMap( Game->GetCurDMap() ) );
  187.     WarpSparkleScreen(Game->GetCurScreen());
  188.     WarpSparkleReturn(Game->GetCurDMap());
  189. }
  190.  
  191. //Removes the warp sparkle, after using it.
  192. void ClearWarpSparkle(){
  193.     WarpSparkle(false);
  194.     WarpSparkleX(-100);
  195.     WarpSparkleY(-100);
  196.     WarpSparkleDMap(-1);
  197.     WarpSparkleScreen(-1);
  198.     WarpSparkleReturn(-1);
  199. }
  200.  
  201. //Returns if Link is in a dungeon based on the array dungeonDMaps[]
  202. //!! You must set up the array inside this function, for it to work.
  203. bool IsDungeonDMap(){
  204.     int dungeonDMaps[]={20,21,22};//List all dungeon DMaps here
  205.     for ( int q = 0; q < SizeOfArray(dungeonDMaps); q++ ) {
  206.         if ( Game->GetCurDMap() == dungeonDMaps[q] ) return true;
  207.         return false;
  208.     }
  209. }
  210.  
  211. //Returns if the warp destination is solid, prior to warping.
  212. bool ___WarpDestSolid(int x, int y, int screen, int map){
  213.     return ( Game->GetComboSolid(map, screen, ComboAt(x,y)) );
  214. }
  215.    
  216.  
  217. //A very precise way to check if the warp destination is solid, based on Link's standard hitbox.
  218. //Checks if any of Link's corners or axis positions are on a solid combo, and if a
  219. bool WarpDestSolid(){
  220.     if ( Screen->isSolid(Link->X+4, Link->Y) ||
  221.         Screen->isSolid(Link->X+8, Link->Y+8) ||
  222.         Screen->isSolid(Link->X+4, Link->Y+8) ||
  223.         Screen->isSolid(Link->X+8, Link->Y) ||
  224.         Screen->isSolid(Link->X+8, Link->Y+15) ||
  225.         Screen->isSolid(Link->X+15, Link->Y+8)  || 
  226.         Screen->isSolid(Link->X+15, Link->Y) ||
  227.         Screen->isSolid(Link->X+4, Link->Y+15) ||
  228.         Screen->isSolid(Link->X+15, Link->Y+15)) return true;
  229.     return false;
  230. }
  231. //! Main Functions to Call before Waitdraw()
  232.  
  233. //Handles the initial warp routines.
  234. void MirrorWarpLink() {
  235.     if ( IsWarping() ){
  236.         Link->X = Mirror[WARP_LINK_X];
  237.         Link->Y = Mirror[WARP_LINK_Y];
  238.         SetPostWarpTimer();
  239.         NoAction();
  240.         Game->PlaySound(SFX_WARP);
  241.         Link->PitWarp(GetOtherworldlyDMap(Game->GetCurDMap()), Game->GetCurScreen());
  242.         Screen->Wavy = WARP_WAVE_DUR;
  243.        
  244.         //Freeze all enemies and ghost scripts
  245.         for(int q = (WARP_WAVE_DUR + POST_WARP_DELAY); q > 0; q--){
  246.             NoAction();
  247.             Waitframe();
  248.         }
  249.         //resume npcs and ghost scripts
  250.        
  251.         IsWarping(false);
  252.         //for(int q = (WARP_WAVE_DUR + POST_WARP_DELAY) / 2; q > 0; q--){
  253.         //  NoAction();
  254.         //  Waitframe();
  255.         //}
  256.         AfterWarp(true);
  257.     }
  258.    
  259.     if (IsReturnWarping() ){
  260.         Mirror[WARP_LINK_HP] = Link->HP;
  261.  
  262.         Link->X = WarpSparkleX();
  263.         Link->Y = WarpSparkleY();
  264.         NoAction();
  265.        
  266.         Link->PitWarp(WarpSparkleReturn(), WarpSparkleScreen());
  267.         Game->PlaySound(SFX_WARP);
  268.         Screen->Wavy = WARP_WAVE_DUR;
  269.         //Freeze all enemies and ghost scripts
  270.         for(int q = (WARP_WAVE_DUR + POST_WARP_DELAY); q > 0; q--){
  271.             NoAction();
  272.             Waitframe();
  273.         }
  274.         //resume npcs and ghost scripts
  275.        
  276.        
  277.         IsReturnWarping(false);
  278.         //for(int q = (WARP_WAVE_DUR + POST_WARP_DELAY) / 2; q > 0; q--){
  279.         //  NoAction();
  280.         //  Waitframe();
  281.         //}
  282.         AfterReturnWarp(true);
  283.     }
  284. }
  285.  
  286. //Post-warp cleanup, and bounce.
  287. void WarpFinish() {
  288.     if (AfterWarp()){
  289.         if ( Link->Action == LA_GOTHURTLAND || Link->Action == LA_GOTHURTWATER ) Link->HitDir = -1;
  290.         //SetWarpReturn();
  291.         //If the destination is solid, send Link back.
  292.         if ( WarpDestSolid() ) {
  293.             ClearWarpSparkle();
  294.             Game->PlaySound(SFX_WARP_ERROR);
  295.             WaitNoAction();
  296.             Screen->Wavy = WARP_WAVE_DUR;
  297.             //freeze all enemies and ghost scripts.
  298.             for(int q = (WARP_WAVE_DUR + POST_WARP_DELAY); q > 0; q--){
  299.                 NoAction();
  300.                 Waitframe();
  301.             }
  302.             //resume npcs and ghost scripts
  303.             Link->X = Mirror[WARP_LINK_X];
  304.             Link->Y = Mirror[WARP_LINK_Y];
  305.             Link->PitWarp(GetOtherworldlyDMap(Game->GetCurDMap()), Game->GetCurScreen());
  306.             //Screen->Wavy = WARP_WAVE_DUR;
  307.            
  308.             AfterWarp(false);
  309.             for(int q = (WARP_WAVE_DUR + POST_WARP_DELAY); q > 0; q--){
  310.                 NoAction();
  311.                 Waitframe();
  312.             }
  313.         }
  314.         if ( Link->HP < Mirror[WARP_LINK_HP] && WARP_RETURNS_ON_INJURY) { //If Link is injured, send him back.
  315.             Link->HP = Mirror[WARP_LINK_HP];
  316.             Game->PlaySound(SFX_WARP);
  317.             Screen->Wavy = WARP_WAVE_DUR;
  318.             //freeze all enemies and ghost scripts.
  319.             for(int q = (WARP_WAVE_DUR + POST_WARP_DELAY) / 2; q > 0; q--){
  320.                 NoAction();
  321.                 Waitframe();
  322.             }
  323.             //resume npcs and ghost scripts
  324.             Link->X = Mirror[WARP_LINK_X];
  325.             Link->Y = Mirror[WARP_LINK_Y];
  326.             Link->PitWarp(WarpSparkleReturn(), Game->GetCurScreen());
  327.  
  328.             Link->X = Mirror[WARP_LINK_X];
  329.             Link->Y = Mirror[WARP_LINK_Y];
  330.             Link->HP = Mirror[WARP_LINK_HP];
  331.            
  332.             AfterWarp(false);
  333.             for(int q = (WARP_WAVE_DUR + POST_WARP_DELAY) / 2; q > 0; q--){
  334.                 NoAction();
  335.                 Waitframe();
  336.             }
  337.         }
  338.         else {
  339.             Link->X = Mirror[WARP_LINK_X];
  340.             Link->Y = Mirror[WARP_LINK_Y];
  341.             //SetPostWarpTimer();
  342.             //Mirror[WARP_LINK_TEMP_INVULNERABILITY] = WARP_INVULNERABILITY_FRAMES;
  343.             AfterWarp(false);
  344.         }
  345.     }
  346.    
  347.     if (AfterReturnWarp()){
  348.         if ( Link->Action == LA_GOTHURTLAND || Link->Action == LA_GOTHURTWATER ) Link->HitDir = -1;
  349.         ClearWarpSparkle();
  350.         Mirror[WARP_LINK_TEMP_INVULNERABILITY] = WARP_INVULNERABILITY_FRAMES;
  351.         AfterReturnWarp(false);
  352.         ClearPostWarpTimer();
  353.            
  354.     }
  355.    
  356.     if ( POST_WARP_LINK_IS_INVINCIBLE ) {
  357.         if ( Mirror[WARP_LINK_TEMP_INVULNERABILITY] ) {
  358.             //If we find a way to Flicker Link, it goes here.
  359.             Link->CollDetection = false;
  360.             Mirror[WARP_LINK_TEMP_INVULNERABILITY]--;
  361.         }
  362.         if ( !Mirror[WARP_LINK_TEMP_INVULNERABILITY] ) Link->CollDetection = true;
  363.     }
  364.    
  365.     //if ( Mirror[MIRROR_POST_WARP_TIMER] > 0 ) Mirror[MIRROR_POST_WARP_TIMER]--;
  366. }
  367.  
  368.  
  369. //Creates the mirror return sparkle.
  370. void MirrorSparkle(){
  371.     if ( Game->GetCurDMap() == WarpSparkleDMap() && Game->GetCurScreen() == WarpSparkleScreen() ) {
  372.         Screen->DrawCombo(  MIRROR_SPARKLE_COMBO_LAYER, WarpSparkleX(), WarpSparkleY(),
  373.             MIRROR_SPARKLE_COMBO, MIRROR_SPARKLE_COMBO_H, MIRROR_SPARKLE_COMBO_W, MIRROR_SPARKLE_COMBO_CSET,
  374.             MIRROR_SPARKLE_COMBO_XSCALE, MIRROR_SPARKLE_COMBO_YSCALE, MIRROR_SPARKLE_COMBO_RX,
  375.             MIRROR_SPARKLE_COMBO_RY, MIRROR_SPARKLE_COMBO_RANGLE, Mirror[MIRROR_SPARKLE_COMBO_FRAME],
  376.             MIRROR_SPARKLE_COMBO_FLIP, true, MIRROR_SPARKLE_COMBO_OPACITY) ; //Mirror sparkle
  377.        
  378.         //Reduce the frames
  379.         if ( Mirror[MIRROR_SPARKLE_COMBO_FRAME] >= MIRROR_SPARKLE_COMBO_NUM_FRAMES ) Mirror[MIRROR_SPARKLE_COMBO_FRAME] = MIRROR_SPARKLE_COMBO_INIT_FRAME;
  380.         else Mirror[MIRROR_SPARKLE_COMBO_FRAME]++;
  381.            
  382.         if ( !WarpReturnWait() && !IsTempInvincible() ){
  383.            
  384.             if ( Abs( Link->X - WarpSparkleX()) < 8 && Abs(Link->Y - WarpSparkleY()) < 8 )
  385.             {
  386.                 //Reurn Link via the portal
  387.                 IsReturnWarping(true);
  388.             }
  389.         }
  390.     }
  391. }
  392.  
  393. bool IsTempInvincible(){
  394.     if ( Mirror[WARP_LINK_TEMP_INVULNERABILITY] && POST_WARP_LINK_IS_INVINCIBLE ) return true;
  395.     if ( !Mirror[WARP_LINK_TEMP_INVULNERABILITY] || !POST_WARP_LINK_IS_INVINCIBLE ) return false;
  396. }
  397.  
  398. void TestSparkle(){
  399.     int x = WarpSparkleX();
  400.     int y = WarpSparkleY();
  401.     if ( x < 0 ) x = 0;
  402.     if ( y < 0 ) y = 0;
  403.     Screen->DrawCombo(  MIRROR_SPARKLE_COMBO_LAYER, x, y,
  404.             MIRROR_SPARKLE_COMBO, MIRROR_SPARKLE_COMBO_H, MIRROR_SPARKLE_COMBO_W, MIRROR_SPARKLE_COMBO_CSET,
  405.             MIRROR_SPARKLE_COMBO_XSCALE, MIRROR_SPARKLE_COMBO_YSCALE, MIRROR_SPARKLE_COMBO_RX,
  406.             MIRROR_SPARKLE_COMBO_RY, MIRROR_SPARKLE_COMBO_RANGLE, Mirror[MIRROR_SPARKLE_COMBO_FRAME],
  407.             MIRROR_SPARKLE_COMBO_FLIP, true, MIRROR_SPARKLE_COMBO_OPACITY) ; //Mirror sparkle
  408.        
  409.         //Reduce the frames
  410.         if ( Mirror[MIRROR_SPARKLE_COMBO_FRAME] >= MIRROR_SPARKLE_COMBO_NUM_FRAMES ) Mirror[MIRROR_SPARKLE_COMBO_FRAME] = MIRROR_SPARKLE_COMBO_INIT_FRAME;
  411.         else Mirror[MIRROR_SPARKLE_COMBO_FRAME]++;
  412. }
  413.  
  414.  
  415. //Runs the moon pearl bunny sprite change, and halts using any item other than the mirror.
  416. void MoonPearl(){
  417.     if ( IsDarkWorld() && !Link->Item[I_MOONPEARL] && !Link->Item[I_BUNNYRING] ) Link->Item[I_BUNNYRING] = true;
  418.     if ( !IsDarkWorld() && Link->Item[I_BUNNYRING] ) Link->Item[I_BUNNYRING] = false;
  419.     if ( IsDarkWorld() && Link->Item[I_MOONPEARL] && Link->Item[I_BUNNYRING] ) Link->Item[I_BUNNYRING] = false;
  420.     if ( Link->Item[I_BUNNYRING] ) {
  421.         if ( Link->PressA && GetEquipmentA() != I_MIRROR ) Link->PressA = false;
  422.         if ( Link->PressB && GetEquipmentB() != I_MIRROR ) Link->PressB = false;
  423.     }
  424. }
  425.  
  426. /// Items
  427.  
  428. item script Mirror{
  429.     void run(){
  430.         int cmb[4];
  431.         cmb[0] = Screen->ComboT[ComboAt(Link->X+8, Link->Y+8)];
  432.         cmb[1] = GetLayerComboT(1,cmb[0]);
  433.         cmb[2] = GetLayerComboT(2,cmb[0]);
  434.         if ( IsDungeonDMap() && MIRROR_RETURNS_TO_DUNGEON_ENTRANCE ) {
  435.             //Warp to dungeon entrance.
  436.             Game->PlaySound(SFX_WARP_DUNGEON);
  437.             Screen->Wavy = WARP_WAVE_DUR_DUNGEON;
  438.             Link->Warp(Game->GetCurDMap(), Game->DMapContinue[Game->GetCurDMap()]);
  439.         }
  440.        
  441.        
  442.         else {
  443.             if ( IsDarkWorld() ) {
  444.                 for ( cmb[3] = 0; cmb[3] <= 3; cmb[3]++ ) {
  445.                     if ( cmb[ cmb[3] ] == CT_CAVE || cmb[ cmb[3] ] == CT_CAVE2 || cmb[ cmb[3] ] == CT_CAVEB
  446.                         || cmb[ cmb[3] ] == CT_CAVEC || cmb[ cmb[3] ] == CT_CAVED ||
  447.                         cmb[ cmb[3] ] == CT_CAVE2B || cmb[ cmb[3] ] == CT_CAVE2C ||cmb[ cmb[3] ] == CT_CAVE2D )
  448.                     {
  449.                         Game->PlaySound(SFX_WARP_ERROR);
  450.                         Quit();
  451.                     }
  452.                 }
  453.                 SetPostWarpTimer();
  454.                 //Mirror[MIRROR_POST_WARP_TIMER] = MIRROR_POST_WARP_TIMER_NUM_FRAMES;
  455.                 Mirror[WARP_LINK_X] = Link->X;
  456.                 Mirror[WARP_LINK_Y] = Link->Y;
  457.                 Mirror[WARP_LINK_HP] = Link->HP;
  458.                 SetWarpReturn();
  459.                 IsWarping(true);
  460.             }
  461.             //Warp to other world
  462.             if ( !IsDarkWorld() && SFX_WARP_ERROR ) Game->PlaySound(SFX_WARP_ERROR);
  463.         }
  464.     }
  465. }
  466.  
  467. //Global Script Example
  468.  
  469. global script Z3_Mirror{
  470.     void run(){
  471.         while(true){
  472.             if ( REQUIRE_MOON_PEARL ) MoonPearl();
  473.             ReducePostWarpTimer();
  474.             MirrorWarpLink();
  475.            
  476.             //if ( TEST_MIRROR_SPARKLE ) TestSparkle();
  477.             //if ( MIRROR_SPARKLE_BEFORE_WAITDRAW ) MirrorSparkle();
  478.             WarpFinish();
  479.             Waitdraw();
  480.            
  481.             //if ( !MIRROR_SPARKLE_BEFORE_WAITDRAW ) MirrorSparkle();
  482.             if ( WarpSparkle() ) MirrorSparkle(); //Call only if it exists.
  483.             Waitframe();
  484.         }
  485.     }
  486. }
  487.  
  488. //Deprecated
  489.  
  490. const int SOLIDITY_CHECK_DISTANCE = 8;
  491.  
  492. bool TouchingSolid(int x, int y) {
  493.     if ( Screen->isSolid(x,y) ||
  494.         Screen->isSolid(x + SOLIDITY_CHECK_DISTANCE, y) ||
  495.         Screen->isSolid(x + SOLIDITY_CHECK_DISTANCE, y+SOLIDITY_CHECK_DISTANCE) ||
  496.         Screen->isSolid(x + SOLIDITY_CHECK_DISTANCE, y-SOLIDITY_CHECK_DISTANCE) ||
  497.         Screen->isSolid(x - SOLIDITY_CHECK_DISTANCE, y) ||
  498.         Screen->isSolid(x - SOLIDITY_CHECK_DISTANCE, y+SOLIDITY_CHECK_DISTANCE) ||
  499.         Screen->isSolid(x - SOLIDITY_CHECK_DISTANCE, y-SOLIDITY_CHECK_DISTANCE) ) {
  500.         return true;
  501.     }
  502.     return false;
  503. }
  504.  
  505. bool TouchingSolid(){
  506.     if ( Screen->isSolid(Link->X,Link->Y) ||
  507.         Screen->isSolid(Link->X + 15, Link->Y) ||
  508.         Screen->isSolid(Link->X + 15, Link->Y+15) ||
  509.         Screen->isSolid(Link->X + 15, Link->Y-15) ||
  510.         Screen->isSolid(Link->X - 15, Link->Y) ||
  511.         Screen->isSolid(Link->X - 15, Link->Y+15) ||
  512.         Screen->isSolid(Link->X - 15, Link->Y-15) )
  513.     {
  514.         return true;
  515.     }
  516.     return false;
  517. }
  518.  
  519.  
  520.  
  521. //Cape
  522.  
  523. //Cane of Byrna
  524.  
  525. //! I need to include these, along with IsInvisible() and IsInvincible() to ensure that there ar eno comflicts between this and other cape/cane scripts.
  526.  
  527. const int CAPE_ON = 50;
  528. const int BYRNA_ON = 51;
  529.  
  530.  
  531. const int CAPE_MAGIC_COST = 3; //Cost per rate
  532. const int CAPE_MAGIC_USE_RATE = 50; //frames per cost unit
  533.  
  534. const int BYRNA_COST = 4;
  535. const int BYRNA_MAGIC_USE_RATE = 120; //frames per unit of cost
  536.  
  537.  
  538. const int CAPE_TIMER = 60;
  539. const int CAPE_SHADOW_WAVER_TIMER = 61;
  540.  
  541. const int BYRNA_TIMER = 70;
  542.  
  543. void InitByrnaTimer() { Mirror[BYRNA_TIMER] = BYRNA_MAGIC_USE_RATE; }
  544.  
  545. void ByrnaCost(){
  546.     if ( Mirror[BYRNA_TIMER] > 0 ) Mirror[BYRNA_TIMER]--;
  547.     if ( Mirror[BYRNA_TIMER] <= 0 ) {
  548.         Game->MCounter[CR_MAGIC] -= ( CAPE_MAGIC_COST * Game->Generic[GEN_MAGICDRAINRATE]; //Allow half magic
  549.         InitByrnaTimer();
  550.     }
  551. }
  552.  
  553. //Array Indices
  554.  
  555. //The true z3 cane has only one orbit
  556. const int BYRNA_BEAM_SPRITE         = 80;
  557. const int BYRNA_BEAM_1_ORBIT_X      = 81;
  558. const int BYRNA_BEAM_1_ORBIT_Y      = 82;
  559. const int BYRNA_BEAM_1_ORBIT_VELOCITY   = 83;
  560. const int BYRNA_BEAM_1_ORBIT_SIN    = 84;
  561. const int BYRNA_BEAM_1_ORBIT_COSIN  = 85;
  562.  
  563. const int BYRNA_BEAM_2_ORBIT_X      = 86;
  564. const int BYRNA_BEAM_2_ORBIT_Y      = 87;
  565. const int BYRNA_BEAM_2_ORBIT_VELOCITY   = 88;
  566. const int BYRNA_BEAM_2_ORBIT_SIN    = 89;
  567. const int BYRNA_BEAM_2_ORBIT_COSIN  = 90;
  568.  
  569. const int BYRNA_BEAM_3_ORBIT_X      = 91;
  570. const int BYRNA_BEAM_3_ORBIT_Y      = 92;
  571. const int BYRNA_BEAM_3_ORBIT_VELOCITY   = 93;
  572. const int BYRNA_BEAM_3_ORBIT_SIN    = 94;
  573. const int BYRNA_BEAM_3_ORBIT_COSIN  = 95;
  574.  
  575. const int BYRNA_BEAM_4_ORBIT_X      = 96;
  576. const int BYRNA_BEAM_4_ORBIT_Y      = 97;
  577. const int BYRNA_BEAM_4_ORBIT_VELOCITY   = 98;
  578. const int BYRNA_BEAM_4_ORBIT_SIN    = 99;
  579. const int BYRNA_BEAM_4_ORBIT_COSIN  = 100;
  580.  
  581. const int CAPE_SHADOW_TILE = 2100;
  582.  
  583. const int WDS_BYRNABLOCKED = 0; //Deadstate for eweapons blocked by the byrna beam.
  584. const int BYRNA_BEAMS_REFLECT_WEAPONS = 1;
  585. const int BYRNA_DAMAGE = 2;
  586. const int LW_CUSTOMBYRNA = 20;
  587. const int BYRNA_NUM_ORBITS = 1;
  588.  
  589.  
  590. void InitCapeTimer() { Mirror[CAPE_TIMER] = CAPE_MAGIC_USE_RATE; }
  591.  
  592. void ByrnaCost(){
  593.     if ( Mirror[BYRNA_TIMER] > 0 ) Mirror[BYRNA_TIMER]--;
  594.     if ( Mirror[BYRNA_TIMER] <= 0 ) {
  595.         Game->MCounter[CR_MAGIC] -= ( CAPE_MAGIC_COST * Game->Generic[GEN_MAGICDRAINRATE]; //Allow half magic
  596.         InitByrnaTimer();
  597.     }
  598. }
  599.  
  600.  
  601. void DoByrna(){
  602.     //lweapon beam[5]; //These will orbit Link;
  603.     int q[8];
  604.    
  605.     //Create the beams and have them orbit Link
  606.     //track their positions in Misc indices
  607.    
  608.     //No, wait, the beams need to be drawn tiles and we need TileCollision.
  609.    
  610.     q[4] = Screen->NummNPCs(); q[5] = Screen->NumEWeapons();
  611.     int loops = Max(npcs,
  612.     for ( q[0] = Max(q[4], q[5]); q > 0; q-- ) {
  613.         if ( q[0] < q[4] ) npc n = Screen->LoadNPC(q[0]);
  614.         if ( q[0] < q[5] ) eweapon e = Screen->LoadEWeapon(q[0]);
  615.         for ( q[1] = 0; q[1] < BYRNA_NUM_ORBITS; q[1]++ ) { //for each beam
  616.             if ( DrawTileCollision(n, beam[ q[1] ]) ) {
  617.                 beam[ q[0] ] = Screen->CreateLWeapon(LW_CUSTOMBYRNA);
  618.                 beam[ q[0] ]-> X = n->X;
  619.                 beam[ q[0] ]-> Y = n->Y; //Spawn a weapon n the npc
  620.                 beam[ q[0] ]->Damage = BYRNA_DAMAGE;
  621.             }
  622.             if ( DrawTileCollision(e, beam[ q[1] ] ) {
  623.                 if ( BYRNA_BEAMS_REFLECT_WEAPONS ) ReflectWeapon(e);
  624.                 else e->DeasDtate = WDS_BYRNABLOCKED:
  625.             }
  626.         }
  627.     }
  628. }
  629.  
  630.  
  631.     }
  632.  
  633.  
  634.  
  635. //if ( Mirror[CAPE_ON] ) {
  636. //  CapeCost();
  637. //  DoCape();
  638. //}
  639.  
  640. void DoCape(){
  641.     int scale = Rand(13,15);
  642.     int flip;
  643.     if ( Link->Dir == DIR_DOWN ) flip = 1;
  644.     else if ( Link->Dir == DIR_LEFT ) flip = 7;
  645.     else if ( Link->Dir == DIR_DOWN ) flip = ;
  646.     else flip = 0;
  647.     Screen->DrawTile(CAPE_SHADOW_LAYER, Link->X+CAPE_SHADOW_X_OFFSET, Link->Y+CAPE_SHADOW_Y_OFFSET, CAPE_SHADOW_TILE, 1,1, CAPE_SHADOW_CSET, scale, scale, 0, 0, 0, flip, true, CAPE_SHADOW_OPACITY);
  648. }
  649.  
  650. const int CAPE_SHADOW_LAYER = 2;
  651. const int CAPE_SHADOW_X_OFFSET = 0;
  652. const int CAPE_SHADOW_Y_OFFSET = 4;
  653. const int CAPE_SHADOW_TILE = 2001;
  654. const int CAPE_SHADOW_CSET = 0;
  655. const int CAPE_SHADOW_OPACITY = 64;
  656.  
  657.  
  658.  
  659.  
  660.  
  661. item script CapeOfInvisibility{
  662.     void run(){
  663.         if ( Mirror[CAPE_ON] ) { Mirror[CAPE_ON] = 0; }
  664.         else {
  665.             InitCapeTimer(); //Should we start at 0 to ensure a magic cost?
  666.             Mirror[CAPE_ON] = 1;
  667.         }
  668.     }
  669. }
  670.  
  671. item script CaneOfByrna{
  672.     void run(){
  673.         if ( Mirror[BYRNA_ON] ) { Mirror[BYRNA_ON] = 0; }
  674.         else Mirror[BYRNA_ON] = 1;
  675.     }
  676. }
  677.  
  678. void CaneOfByrna(){}
  679. void CapeOfInvisibility(){}
  680.  
  681. bool IsInvisible(){
  682.     if ( Mirror[CAPE_ON] ) return true;
  683.     return false;
  684. }
  685.  
  686. bool IsInvincible(){
  687.     if ( Mirror[BYRNA_ON] || Mirror[WARP_LINK_TEMP_INVULNERABILITY] ) return true;
  688.     return false;
  689. }
  690.  
  691. void HandleInvisibilityAndInvincibility(){
  692.     if ( IsInvisible() ) Link->Invisible = true;
  693.     else Link->Invisible = false;
  694.     if ( IsInvincible() ) Link->CollDetection = false;
  695.     else Link->CollDetection = true;
  696. }
  697.  
  698. //! We can tighten this down baed on Link's proximity to the grid.
  699. bool LinkTouchingSolidCombo(){
  700.     int cmb[6];
  701.     cmb[0] = ComboAt(Link->X, Link->Y);
  702.     cmb[1] = ____AdjacentCombo(cmb,3);
  703.     cmb[2] = ____AdjacentCombo(cmb,5);
  704.     cmb[3] = ____AdjacentCombo(cmb,4);
  705.     for ( cmb[4] = 0; cmb[4] <= 2; cmb[4]++ ) {
  706.         for ( cmb[5] = 0; cmb[5] <= 4; cmb[5]++ ) {
  707.             if ( GetLayerComboS(cmb[4], cmb[ cmb[5] ]) > 0 ) return true;
  708.         }
  709.     }
  710. }
  711.  
  712.  
  713. //Constants for AdjacentCombo()
  714.  
  715. //const int CMB_UPLEFT    = 0;
  716. //const int CMB_UP        = 1;
  717. //const int CMB_UPRIGHT   = 2;
  718. //const int CMB_RIGHT     = 3;
  719. //const int CMB_DOWNRIGHT = 4;
  720. //const int CMB_DOWN      = 5;
  721. //const int CMB_DOWNLEFT  = 6;
  722. //const int CMB_LEFT      = 7;
  723. //const int CMB_LEFTUP    = 0; //Not 8, as those are dir + shield
  724.  
  725. //Returns the Nuth combo index of a combo based on a central point, and a direction.
  726. //For example, combo 22 + COMBO_UPRIGHT returns '7',
  727. //as combo 7 is to the upper-right of combo 22.
  728. int ____AdjacentCombo(int cmb, int dir){
  729.     int combooffsets[13]={-0x10,-0x0F,-0x0E,1,0x10,0x0F,0x0E,-1,-0x10};
  730.     if ( cmb % 16 == 0 ) combooffsets[9] = 1;
  731.     if ( (cmb & 15) == 1 ) combooffsets[10] = 1;
  732.     if ( cmb < 0x10 ) combooffsets[11] = 1;
  733.     if ( cmb < 0xAF ) combooffsets[12] = 1;
  734.     if ( combooffsets[9] && ( dir == CMB_LEFT || dir == CMB_UPLEFT || dir == CMB_DOWNLEFT || dir == CMB_LEFTUP ) ) return 0;
  735.     if ( combooffsets[10] && ( dir == CMB_RIGHT || dir == CMB_UPRIGHT || dir == CMB_DOWNRIGHT ) ) return 0;
  736.     if ( combooffsets[11] && ( dir == CMB_UP || dir == CMB_UPRIGHT || dir == CMB_UPLEFT || dir == CMB_DOWNLEFT ) ) return 0;
  737.     if ( combooffsets[12] && ( dir == CMB_DOWN || dir == CMB_DOWNRIGHT || dir == CMB_DOWNLEFT ) ) return 0;
  738.     else if ( cmb > 0 && cmb < 177 ) return cmb + combooffsets[dir];
  739.     else return 0;
  740. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement