Advertisement
ZoriaRPG

ZScript: Z3 Style Magic Mirror (v0.1.6, Compiles)

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