Advertisement
ZoriaRPG

ZScript: Z3 Style Magic Mirror (v0.2.4, Tested, Working)

Nov 22nd, 2016
174
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 14.53 KB | None | 0 0
  1. ///////////////////////
  2. /// Z3 Magic Mirror ///
  3. /// v0.2.4          ///
  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. /// Global Array
  18. int Mirror[214747];
  19.  
  20. const int TEST_MIRROR_SPARKLE = 0;
  21. const int MIRROR_SPARKLE_BEFORE_WAITDRAW = 0;
  22.  
  23. //Moon Pearl Goodies
  24. const int I_MIRROR = 160;
  25. const int I_MOONPEARL = 200;
  26. const int I_BUNNYRING = 201; //A wisp ring twith a LTM for Bunny Sprites
  27.  
  28. //Options
  29. const int WARP_RETURNS_ON_INJURY        = 1;
  30. const int REQUIRE_MOON_PEARL            = 1;
  31. const int MIRROR_RETURNS_TO_DUNGEON_ENTRANCE    = 1; //This requires placing a warp return square on dungeon entrance screens.
  32.  
  33. const int MIRROR_POST_WARP_TIMER_NUM_FRAMES = 75; // Number of frames afer warping, before Link may use a warp return sparkle.
  34.  
  35. const int POST_WARP_LINK_IS_INVINCIBLE      = 0;     //If se tto '1', Link->CollDetection will be disabled for a number of
  36.                         //frames equal to:
  37.  
  38. const int WARP_INVULNERABILITY_FRAMES       = 90; //Number of frames that Link is invulnerable after warping.
  39.  
  40. //!! Caution: This may conflict with other items that grant invulnerability!
  41.  
  42.  
  43. ///Constants for Array Indices of Mirror[]
  44.  
  45. const int IS_WARPING        = 0;
  46. const int AFTER_WARP        = 1;
  47. const int RETURN_WARP       = 2;
  48. const int AFTER_RETURN_WARP     = 3;
  49.  
  50. const int WARP_SPARKLE          = 10;
  51. const int WARP_SPARKLE_DMAP         = 11;
  52. const int WARP_SPARKLE_SCREEN       = 12;
  53. const int WARP_SPARKLE_X        = 13;
  54. const int WARP_SPARKLE_Y        = 14;
  55. const int WARP_SPARKLE_RETURN_DMAP  = 15;
  56.  
  57. const int WARP_LINK_X           = 20;
  58. const int WARP_LINK_Y           = 21;
  59. const int WARP_LINK_Z           = 22;
  60. const int WARP_LINK_HP          = 23;
  61. const int WARP_LINK_TEMP_INVULNERABILITY = 24;
  62.  
  63. const int MIRROR_SPARKLE_COMBO_FRAME = 30; //Mirror array index
  64. const int MIRROR_POST_WARP_TIMER = 40;
  65.  
  66.  
  67.  
  68. //Settings
  69.  
  70. //Sounds
  71. const int SFX_WARP_ERROR    = 67;
  72. const int SFX_WARP      = 73;
  73. const int SFX_WARP_DUNGEON  = 16;
  74.  
  75. const int WARP_WAVE_DUR     = 100; //Duration of warp wavy animation (overworld)
  76. const int WARP_WAVE_DUR_DUNGEON = 100; //Duration of warp wavy animation (inside dungeons)
  77.  
  78. const int WARP_DUR      = 60;
  79. const int POST_WARP_DELAY   = 15;
  80.  
  81.  
  82.  
  83. //Mirror Sparkle Settings
  84. const int MIRROR_SPARKLE_COMBO      = 32596; // COmbo of sparkle or other warp return effect.
  85. const int MIRROR_SPARKLE_COMBO_LAYER    = 2;
  86. const int MIRROR_SPARKLE_COMBO_W    = 1;
  87. const int MIRROR_SPARKLE_COMBO_H    = 1;
  88. const int MIRROR_SPARKLE_COMBO_CSET     = 0;
  89. const int MIRROR_SPARKLE_COMBO_XSCALE   = -1;
  90. const int MIRROR_SPARKLE_COMBO_YSCALE   = -1;
  91. const int MIRROR_SPARKLE_COMBO_RX   = 0;
  92. const int MIRROR_SPARKLE_COMBO_RY   = 0;
  93. const int MIRROR_SPARKLE_COMBO_RANGLE   = 0;
  94.  
  95. const int MIRROR_SPARKLE_COMBO_FLIP     = 0;
  96. const int MIRROR_SPARKLE_COMBO_OPACITY  = 64;
  97.  
  98. const int MIRROR_SPARKLE_COMBO_NUM_FRAMES = 4;
  99. const int MIRROR_SPARKLE_COMBO_INIT_FRAME = 1;
  100.  
  101.  
  102.  
  103.  
  104. //Accessors
  105. int IsWarping(){ return Mirror[IS_WARPING]; }
  106. void IsWarping(bool state){ if ( state ) Mirror[IS_WARPING] = 1; else Mirror[IS_WARPING] = 0; }
  107.  
  108. int AfterWarp(){ return Mirror[AFTER_WARP]; }
  109. void AfterWarp(bool state){ if ( state ) Mirror[AFTER_WARP] = 1; else Mirror[AFTER_WARP] = 0; }
  110.  
  111. int IsReturnWarping(){ return Mirror[RETURN_WARP]; }
  112. void IsReturnWarping(bool state){ if ( state ) Mirror[RETURN_WARP] = 1; else Mirror[RETURN_WARP] = 0; }
  113.  
  114. int AfterReturnWarp(){ return Mirror[AFTER_RETURN_WARP]; }
  115. void AfterReturnWarp(bool state){ if ( state ) Mirror[AFTER_RETURN_WARP] = 1; else Mirror[AFTER_RETURN_WARP] = 0; }
  116.  
  117. int WarpSparkle(){ return Mirror[WARP_SPARKLE]; }
  118. void WarpSparkle(bool state){ if ( state ) Mirror[WARP_SPARKLE] = 1; else Mirror[WARP_SPARKLE] = 0; }
  119.  
  120. int WarpSparkleReturn(){ return Mirror[WARP_SPARKLE_RETURN_DMAP]; }
  121. void WarpSparkleReturn(int dmap){ Mirror[WARP_SPARKLE_RETURN_DMAP] = dmap; }
  122.  
  123. int WarpSparkleDMap(){ return Mirror[WARP_SPARKLE_DMAP]; }
  124. void WarpSparkleDMap(int dmap){ Mirror[WARP_SPARKLE_DMAP] = dmap; }
  125.  
  126. int WarpSparkleX(){ return Mirror[WARP_SPARKLE_X]; }
  127. void WarpSparkleX(int x){ Mirror[WARP_SPARKLE_X] = x; }
  128.  
  129. int WarpSparkleY(){ return Mirror[WARP_SPARKLE_Y]; }
  130. void WarpSparkleY(int y){ Mirror[WARP_SPARKLE_Y] = y; }
  131.  
  132. int WarpSparkleScreen(){ return Mirror[WARP_SPARKLE_SCREEN]; }
  133. void WarpSparkleScreen(int screen){ Mirror[WARP_SPARKLE_SCREEN] = screen; }
  134.  
  135. //The following four functions are used to manipulate,a nd check the post-warp timer,
  136. //that prevents Link from being sent back by a sparkle as soon as he finishes warping.
  137.  
  138. int WarpReturnWait(){ return Mirror[MIRROR_POST_WARP_TIMER]; }
  139. void ReducePostWarpTimer(){ if ( Mirror[MIRROR_POST_WARP_TIMER] > 0 ) Mirror[MIRROR_POST_WARP_TIMER]--; }
  140. void SetPostWarpTimer(){ Mirror[MIRROR_POST_WARP_TIMER] = MIRROR_POST_WARP_TIMER_NUM_FRAMES + WARP_WAVE_DUR + POST_WARP_DELAY; }
  141. void ClearPostWarpTimer(){ Mirror[MIRROR_POST_WARP_TIMER] = 0; }
  142.  
  143.  
  144. //Functions
  145.  
  146. //Checks the present DMap and returns irts counterpart.
  147. //!! You must set up the arrays inside this function, for it to work.
  148. int GetOtherworldlyDMap(int dmap){
  149.     int q[4];
  150.     int LightWorldDMaps[]={3,-1,-1,-1,-1}; //Populate these two arrays with the IDs of your light and dark world dmaps
  151.     int DarkWorldDMaps[]={8,-1,-1,-1,-1}; //in matched pairs.
  152.     for ( q[0] = 0; q[0] < SizeOfArray(LightWorldDMaps); q[0]++ ) {
  153.         q[1] = LightWorldDMaps[ q[0] ];
  154.         q[2] = DarkWorldDMaps[ q[0] ];
  155.         if ( dmap == q[1] ) return DarkWorldDMaps[ q[0] ];
  156.         if ( dmap == q[2] ) return LightWorldDMaps[ q[0] ];
  157.     }
  158.     return -1;
  159. }
  160.  
  161. //Returns if the present dmap is a dark world dmap
  162. //!! You must set up the arrays inside this function, for it to work.
  163. bool IsDarkWorld(){
  164.     int DarkWorldDMaps[]={8,-1,-1,-1,-1};
  165.     for ( int q = 0; q < SizeOfArray(DarkWorldDMaps); q++ ) {
  166.         if ( Game->GetCurDMap() == DarkWorldDMaps[q] ) return true;
  167.     }
  168.     return false;
  169. }
  170.  
  171. //Generates coordinates for the warp return sparkle.
  172. //this is set when we use the mirror.
  173. void SetWarpReturn(){
  174.     WarpSparkle(true);
  175.     WarpSparkleX(Link->X);
  176.     WarpSparkleY(Link->Y);
  177.     WarpSparkleDMap( GetOtherworldlyDMap( Game->GetCurDMap() ) );
  178.     WarpSparkleScreen(Game->GetCurScreen());
  179.     WarpSparkleReturn(Game->GetCurDMap());
  180. }
  181.  
  182. //Removes the warp sparkle, after using it.
  183. void ClearWarpSparkle(){
  184.     WarpSparkle(false);
  185.     WarpSparkleX(-100);
  186.     WarpSparkleY(-100);
  187.     WarpSparkleDMap(-1);
  188.     WarpSparkleScreen(-1);
  189.     WarpSparkleReturn(-1);
  190. }
  191.  
  192. //Returns if Link is in a dungeon based on the array dungeonDMaps[]
  193. //!! You must set up the array inside this function, for it to work.
  194. bool IsDungeonDMap(){
  195.     int dungeonDMaps[]={20,21,22};//List all dungeon DMaps here
  196.     for ( int q = 0; q < SizeOfArray(dungeonDMaps); q++ ) {
  197.         if ( Game->GetCurDMap() == dungeonDMaps[q] ) return true;
  198.         return false;
  199.     }
  200. }
  201.  
  202. //Returns if the warp destination is solid, prior to warping.
  203. bool WarpDestSolid(int x, int y, int screen, int map){
  204.     return ( Game->GetComboSolid(map, screen, ComboAt(x,y)) );
  205. }
  206.    
  207. //! Main Functions to Call before Waitdraw()
  208.  
  209. //Handles the initial warp routines.
  210. void MirrorWarpLink() {
  211.     if ( IsWarping() ){
  212.         SetPostWarpTimer();
  213.         NoAction();
  214.         Game->PlaySound(SFX_WARP);
  215.         Screen->Wavy = WARP_WAVE_DUR;
  216.         //Freeze all enemies and ghost scripts
  217.         for(int q = WARP_WAVE_DUR + POST_WARP_DELAY; q > 0; q--){
  218.             NoAction();
  219.             Waitframe();
  220.         }
  221.         //resume npcs and ghost scripts
  222.         Link->PitWarp(GetOtherworldlyDMap(Game->GetCurDMap()), Game->GetCurScreen());
  223.         IsWarping(false);
  224.         AfterWarp(true);
  225.     }
  226.    
  227.     if (IsReturnWarping() ){
  228.         Mirror[WARP_LINK_HP] = Link->HP;
  229.         Link->X = WarpSparkleX();
  230.         Link->Y = WarpSparkleY();
  231.         NoAction();
  232.         Game->PlaySound(SFX_WARP);
  233.         Screen->Wavy = WARP_WAVE_DUR;
  234.         //Freeze all enemies and ghost scripts
  235.         for(int q = WARP_WAVE_DUR + POST_WARP_DELAY; q > 0; q--){
  236.             NoAction();
  237.             Waitframe();
  238.         }
  239.         //resume npcs and ghost scripts
  240.         Link->PitWarp(WarpSparkleReturn(), WarpSparkleScreen());
  241.         IsReturnWarping(false);
  242.         AfterReturnWarp(true);
  243.     }
  244. }
  245.  
  246. //Post-warp cleanup, and bounce.
  247. void WarpFinish() {
  248.     if (AfterWarp()){
  249.         if ( Link->Action == LA_GOTHURTLAND || Link->Action == LA_GOTHURTWATER ) Link->HitDir = -1;
  250.         //SetWarpReturn();
  251.         //If the destination is solid, send Link back.
  252.         if ( Screen->ComboS[ ComboAt(Link->X, Link->Y) ] ) {
  253.             Game->PlaySound(SFX_WARP);
  254.             Screen->Wavy = WARP_WAVE_DUR;
  255.             //freeze all enemies and ghost scripts.
  256.             for (int q = WARP_WAVE_DUR + POST_WARP_DELAY; q > 0; q--){
  257.                 NoAction();
  258.                 Waitframe();
  259.             }
  260.             //resume npcs and ghost scripts
  261.             Link->X = Mirror[WARP_LINK_X];
  262.             Link->Y = Mirror[WARP_LINK_Y];
  263.             Link->PitWarp(WarpSparkleReturn(), Game->GetCurScreen());
  264.            
  265.             AfterWarp(false);
  266.         }
  267.         if ( Link->HP < Mirror[WARP_LINK_HP] && WARP_RETURNS_ON_INJURY) { //If Link is injured, send him back.
  268.             Link->HP = Mirror[WARP_LINK_HP];
  269.             Game->PlaySound(SFX_WARP);
  270.             Screen->Wavy = WARP_WAVE_DUR;
  271.             //freeze all enemies and ghost scripts.
  272.             for(int q = WARP_WAVE_DUR + POST_WARP_DELAY; q > 0; q--){
  273.                 NoAction();
  274.                 Waitframe();
  275.             }
  276.             //resume npcs and ghost scripts
  277.             Link->X = Mirror[WARP_LINK_X];
  278.             Link->Y = Mirror[WARP_LINK_Y];
  279.             Link->PitWarp(WarpSparkleReturn(), Game->GetCurScreen());
  280.  
  281.             Link->X = Mirror[WARP_LINK_X];
  282.             Link->Y = Mirror[WARP_LINK_Y];
  283.             Link->HP = Mirror[WARP_LINK_HP];
  284.            
  285.             AfterWarp(false);
  286.         }
  287.         else {
  288.             Link->X = Mirror[WARP_LINK_X];
  289.             Link->Y = Mirror[WARP_LINK_Y];
  290.             Mirror[WARP_INVULNERABILITY_FRAMES] = WARP_INVULNERABILITY_FRAMES;
  291.         }
  292.     }
  293.    
  294.     if (AfterReturnWarp()){
  295.         if ( Link->Action == LA_GOTHURTLAND || Link->Action == LA_GOTHURTWATER ) Link->HitDir = -1;
  296.         ClearWarpSparkle();
  297.         Mirror[WARP_INVULNERABILITY_FRAMES] = WARP_INVULNERABILITY_FRAMES;
  298.         AfterReturnWarp(false);
  299.         //ClearPostWarpTimer();
  300.            
  301.     }
  302.    
  303.     if ( POST_WARP_LINK_IS_INVINCIBLE ) {
  304.         if ( Mirror[WARP_INVULNERABILITY_FRAMES] ) {
  305.             Link->CollDetection = false;
  306.             Mirror[WARP_INVULNERABILITY_FRAMES]--;
  307.         }
  308.         if ( !Mirror[WARP_INVULNERABILITY_FRAMES] ) Link->CollDetection = true;
  309.     }
  310. }
  311.  
  312.  
  313. //Creates the mirror return sparkle.
  314. void MirrorSparkle(){
  315.     if ( Game->GetCurDMap() == WarpSparkleDMap() && Game->GetCurScreen() == WarpSparkleScreen() ) {
  316.         Screen->DrawCombo(  MIRROR_SPARKLE_COMBO_LAYER, WarpSparkleX(), WarpSparkleY(),
  317.             MIRROR_SPARKLE_COMBO, MIRROR_SPARKLE_COMBO_H, MIRROR_SPARKLE_COMBO_W, MIRROR_SPARKLE_COMBO_CSET,
  318.             MIRROR_SPARKLE_COMBO_XSCALE, MIRROR_SPARKLE_COMBO_YSCALE, MIRROR_SPARKLE_COMBO_RX,
  319.             MIRROR_SPARKLE_COMBO_RY, MIRROR_SPARKLE_COMBO_RANGLE, Mirror[MIRROR_SPARKLE_COMBO_FRAME],
  320.             MIRROR_SPARKLE_COMBO_FLIP, true, MIRROR_SPARKLE_COMBO_OPACITY) ; //Mirror sparkle
  321.        
  322.         //Reduce the frames
  323.         if ( Mirror[MIRROR_SPARKLE_COMBO_FRAME] >= MIRROR_SPARKLE_COMBO_NUM_FRAMES ) Mirror[MIRROR_SPARKLE_COMBO_FRAME] = MIRROR_SPARKLE_COMBO_INIT_FRAME;
  324.         else Mirror[MIRROR_SPARKLE_COMBO_FRAME]++;
  325.            
  326.         if ( !WarpReturnWait() && RectCollision( Mirror[WARP_SPARKLE_X], Mirror[WARP_SPARKLE_Y], Mirror[WARP_SPARKLE_X]+16, Mirror[WARP_SPARKLE_Y]+16, Link->X+Link->HitXOffset+Link->DrawXOffset, Link->Y+Link->HitYOffset+Link->DrawYOffset, Link->X+Link->HitXOffset+Link->DrawXOffset+Link->HitWidth, Link->Y+Link->HitYOffset+Link->DrawYOffset+Link->HitHeight)
  327.             || Distance(CenterLinkX(), CenterLinkY(), Mirror[WARP_SPARKLE_X]+8, Mirror[WARP_SPARKLE_Y]+8) < 8)
  328.         {
  329.             //Reurn Link via the portal
  330.             IsReturnWarping(true);
  331.         }
  332.     }
  333. }
  334.  
  335. void TestSparkle(){
  336.     int x = WarpSparkleX();
  337.     int y = WarpSparkleY();
  338.     if ( x < 0 ) x = 0;
  339.     if ( y < 0 ) y = 0;
  340.     Screen->DrawCombo(  MIRROR_SPARKLE_COMBO_LAYER, x, y,
  341.             MIRROR_SPARKLE_COMBO, MIRROR_SPARKLE_COMBO_H, MIRROR_SPARKLE_COMBO_W, MIRROR_SPARKLE_COMBO_CSET,
  342.             MIRROR_SPARKLE_COMBO_XSCALE, MIRROR_SPARKLE_COMBO_YSCALE, MIRROR_SPARKLE_COMBO_RX,
  343.             MIRROR_SPARKLE_COMBO_RY, MIRROR_SPARKLE_COMBO_RANGLE, Mirror[MIRROR_SPARKLE_COMBO_FRAME],
  344.             MIRROR_SPARKLE_COMBO_FLIP, true, MIRROR_SPARKLE_COMBO_OPACITY) ; //Mirror sparkle
  345.        
  346.         //Reduce the frames
  347.         if ( Mirror[MIRROR_SPARKLE_COMBO_FRAME] >= MIRROR_SPARKLE_COMBO_NUM_FRAMES ) Mirror[MIRROR_SPARKLE_COMBO_FRAME] = MIRROR_SPARKLE_COMBO_INIT_FRAME;
  348.         else Mirror[MIRROR_SPARKLE_COMBO_FRAME]++;
  349. }
  350.  
  351.  
  352. //Runs the moon pearl bunny sprite change, and halts using any item other than the mirror.
  353. void MoonPearl(){
  354.     if ( IsDarkWorld() && !Link->Item[I_MOONPEARL] && !Link->Item[I_BUNNYRING] ) Link->Item[I_BUNNYRING] = true;
  355.     if ( !IsDarkWorld() && Link->Item[I_BUNNYRING] ) Link->Item[I_BUNNYRING] = false;
  356.     if ( IsDarkWorld() && Link->Item[I_MOONPEARL] && Link->Item[I_BUNNYRING] ) Link->Item[I_BUNNYRING] = false;
  357.     if ( Link->Item[I_BUNNYRING] ) {
  358.         if ( Link->PressA && GetEquipmentA() != I_MIRROR ) Link->PressA = false;
  359.         if ( Link->PressB && GetEquipmentB() != I_MIRROR ) Link->PressB = false;
  360.     }
  361. }
  362.  
  363. /// Items
  364.  
  365. item script Mirror{
  366.     void run(){
  367.         if ( IsDungeonDMap() && MIRROR_RETURNS_TO_DUNGEON_ENTRANCE ) {
  368.             //Warp to dungeon entrance.
  369.             Game->PlaySound(SFX_WARP_DUNGEON);
  370.             Screen->Wavy = WARP_WAVE_DUR_DUNGEON;
  371.             Link->Warp(Game->GetCurDMap(), Game->DMapContinue[Game->GetCurDMap()]);
  372.         }
  373.         else {
  374.             if ( IsDarkWorld() ) {
  375.                 //SetPostWarpTimer();
  376.                 SetWarpReturn();
  377.                 IsWarping(true);
  378.             }
  379.             //Warp to other world
  380.             if ( !IsDarkWorld() && SFX_WARP_ERROR ) Game->PlaySound(SFX_WARP_ERROR);
  381.         }
  382.     }
  383. }
  384.  
  385. //Global Script Example
  386.  
  387. global script Z3_Mirror{
  388.     void run(){
  389.         while(true){
  390.             if ( REQUIRE_MOON_PEARL ) MoonPearl();
  391.             ReducePostWarpTimer();
  392.             MirrorWarpLink();
  393.  
  394.             //if ( TEST_MIRROR_SPARKLE ) TestSparkle();
  395.             //if ( MIRROR_SPARKLE_BEFORE_WAITDRAW ) MirrorSparkle();
  396.             Waitdraw();
  397.             WarpFinish();
  398.             //if ( !MIRROR_SPARKLE_BEFORE_WAITDRAW ) MirrorSparkle();
  399.             if ( WarpSparkle() ) MirrorSparkle(); //Call only if it exists.
  400.             Waitframe();
  401.         }
  402.     }
  403. }
  404.  
  405. //Deprecated
  406.  
  407. //bool TouchingSolid(int x, int y) {
  408.   //  if ( Screen->isSolid(x,y) ||
  409.   //  Screen->isSolid(x + SOLIDITY_CHECK_DISTANCE, y) ||
  410.   //  Screen->isSolid(x + SOLIDITY_CHECK_DISTANCE, y+SOLIDITY_CHECK_DISTANCE) ||
  411.   //  Screen->isSolid(x + SOLIDITY_CHECK_DISTANCE, y-SOLIDITY_CHECK_DISTANCE) ||
  412.   //  Screen->isSolid(x - SOLIDITY_CHECK_DISTANCE, y) ||
  413.   //  Screen->isSolid(x - SOLIDITY_CHECK_DISTANCE, y+SOLIDITY_CHECK_DISTANCE) ||
  414.   //  Screen->isSolid(x - SOLIDITY_CHECK_DISTANCE, y-SOLIDITY_CHECK_DISTANCE) ) {
  415.   //      return true;
  416.   //  }
  417.   //  else {
  418.    //     return false;
  419.   //  }
  420. //}
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement