Advertisement
ZoriaRPG

ZScript: Z3 Style Magic Mirror (v0.2.5, Alternate, Test)

Nov 22nd, 2016
191
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 14.67 KB | None | 0 0
  1. ///////////////////////
  2. /// Z3 Magic Mirror ///
  3. /// v0.2.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. /// 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; }
  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.         Link->X = Mirror[WARP_LINK_X];
  213.         Link->Y = Mirror[WARP_LINK_Y];
  214.         SetPostWarpTimer();
  215.         NoAction();
  216.         Game->PlaySound(SFX_WARP);
  217.         Screen->Wavy = WARP_WAVE_DUR;
  218.         //Freeze all enemies and ghost scripts
  219.         for(int q = WARP_WAVE_DUR + POST_WARP_DELAY; q > 0; q--){
  220.             NoAction();
  221.             Waitframe();
  222.         }
  223.         //resume npcs and ghost scripts
  224.         Link->PitWarp(GetOtherworldlyDMap(Game->GetCurDMap()), Game->GetCurScreen());
  225.         IsWarping(false);
  226.         AfterWarp(true);
  227.     }
  228.    
  229.     if (IsReturnWarping() ){
  230.         Mirror[WARP_LINK_HP] = Link->HP;
  231.  
  232.         Link->X = WarpSparkleX();
  233.         Link->Y = WarpSparkleY();
  234.         NoAction();
  235.         Game->PlaySound(SFX_WARP);
  236.         Screen->Wavy = WARP_WAVE_DUR;
  237.         //Freeze all enemies and ghost scripts
  238.         for(int q = WARP_WAVE_DUR + POST_WARP_DELAY; q > 0; q--){
  239.             NoAction();
  240.             Waitframe();
  241.         }
  242.         //resume npcs and ghost scripts
  243.         Link->PitWarp(WarpSparkleReturn(), WarpSparkleScreen());
  244.         IsReturnWarping(false);
  245.         AfterReturnWarp(true);
  246.     }
  247. }
  248.  
  249. //Post-warp cleanup, and bounce.
  250. void WarpFinish() {
  251.     if (AfterWarp()){
  252.         if ( Link->Action == LA_GOTHURTLAND || Link->Action == LA_GOTHURTWATER ) Link->HitDir = -1;
  253.         //SetWarpReturn();
  254.         //If the destination is solid, send Link back.
  255.         if ( Screen->ComboS[ ComboAt(Link->X, Link->Y) ] ) {
  256.             Game->PlaySound(SFX_WARP);
  257.             Screen->Wavy = WARP_WAVE_DUR;
  258.             //freeze all enemies and ghost scripts.
  259.             for (int q = WARP_WAVE_DUR + POST_WARP_DELAY; q > 0; q--){
  260.                 NoAction();
  261.                 Waitframe();
  262.             }
  263.             //resume npcs and ghost scripts
  264.             Link->X = Mirror[WARP_LINK_X];
  265.             Link->Y = Mirror[WARP_LINK_Y];
  266.             Link->PitWarp(WarpSparkleReturn(), Game->GetCurScreen());
  267.            
  268.             AfterWarp(false);
  269.         }
  270.         if ( Link->HP < Mirror[WARP_LINK_HP] && WARP_RETURNS_ON_INJURY) { //If Link is injured, send him back.
  271.             Link->HP = Mirror[WARP_LINK_HP];
  272.             Game->PlaySound(SFX_WARP);
  273.             Screen->Wavy = WARP_WAVE_DUR;
  274.             //freeze all enemies and ghost scripts.
  275.             for(int q = WARP_WAVE_DUR + POST_WARP_DELAY; q > 0; q--){
  276.                 NoAction();
  277.                 Waitframe();
  278.             }
  279.             //resume npcs and ghost scripts
  280.             Link->X = Mirror[WARP_LINK_X];
  281.             Link->Y = Mirror[WARP_LINK_Y];
  282.             Link->PitWarp(WarpSparkleReturn(), Game->GetCurScreen());
  283.  
  284.             Link->X = Mirror[WARP_LINK_X];
  285.             Link->Y = Mirror[WARP_LINK_Y];
  286.             Link->HP = Mirror[WARP_LINK_HP];
  287.            
  288.             AfterWarp(false);
  289.         }
  290.         else {
  291.             //Link->X = Mirror[WARP_LINK_X];
  292.             //Link->Y = Mirror[WARP_LINK_Y];
  293.             SetPostWarpTimer();
  294.             Mirror[WARP_INVULNERABILITY_FRAMES] = WARP_INVULNERABILITY_FRAMES;
  295.             AfterWarp(false);
  296.         }
  297.     }
  298.    
  299.     if (AfterReturnWarp()){
  300.         if ( Link->Action == LA_GOTHURTLAND || Link->Action == LA_GOTHURTWATER ) Link->HitDir = -1;
  301.         ClearWarpSparkle();
  302.         Mirror[WARP_INVULNERABILITY_FRAMES] = WARP_INVULNERABILITY_FRAMES;
  303.         AfterReturnWarp(false);
  304.         //ClearPostWarpTimer();
  305.            
  306.     }
  307.    
  308.     if ( POST_WARP_LINK_IS_INVINCIBLE ) {
  309.         if ( Mirror[WARP_INVULNERABILITY_FRAMES] ) {
  310.             //If we find a way to Flicker Link, it goes here.
  311.             Link->CollDetection = false;
  312.             Mirror[WARP_INVULNERABILITY_FRAMES]--;
  313.         }
  314.         if ( !Mirror[WARP_INVULNERABILITY_FRAMES] ) Link->CollDetection = true;
  315.     }
  316. }
  317.  
  318.  
  319. //Creates the mirror return sparkle.
  320. void MirrorSparkle(){
  321.     if ( Game->GetCurDMap() == WarpSparkleDMap() && Game->GetCurScreen() == WarpSparkleScreen() ) {
  322.         Screen->DrawCombo(  MIRROR_SPARKLE_COMBO_LAYER, WarpSparkleX(), WarpSparkleY(),
  323.             MIRROR_SPARKLE_COMBO, MIRROR_SPARKLE_COMBO_H, MIRROR_SPARKLE_COMBO_W, MIRROR_SPARKLE_COMBO_CSET,
  324.             MIRROR_SPARKLE_COMBO_XSCALE, MIRROR_SPARKLE_COMBO_YSCALE, MIRROR_SPARKLE_COMBO_RX,
  325.             MIRROR_SPARKLE_COMBO_RY, MIRROR_SPARKLE_COMBO_RANGLE, Mirror[MIRROR_SPARKLE_COMBO_FRAME],
  326.             MIRROR_SPARKLE_COMBO_FLIP, true, MIRROR_SPARKLE_COMBO_OPACITY) ; //Mirror sparkle
  327.        
  328.         //Reduce the frames
  329.         if ( Mirror[MIRROR_SPARKLE_COMBO_FRAME] >= MIRROR_SPARKLE_COMBO_NUM_FRAMES ) Mirror[MIRROR_SPARKLE_COMBO_FRAME] = MIRROR_SPARKLE_COMBO_INIT_FRAME;
  330.         else Mirror[MIRROR_SPARKLE_COMBO_FRAME]++;
  331.            
  332.         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)
  333.             || Distance(CenterLinkX(), CenterLinkY(), Mirror[WARP_SPARKLE_X]+8, Mirror[WARP_SPARKLE_Y]+8) < 8)
  334.         {
  335.             //Reurn Link via the portal
  336.             IsReturnWarping(true);
  337.         }
  338.     }
  339. }
  340.  
  341. void TestSparkle(){
  342.     int x = WarpSparkleX();
  343.     int y = WarpSparkleY();
  344.     if ( x < 0 ) x = 0;
  345.     if ( y < 0 ) y = 0;
  346.     Screen->DrawCombo(  MIRROR_SPARKLE_COMBO_LAYER, x, y,
  347.             MIRROR_SPARKLE_COMBO, MIRROR_SPARKLE_COMBO_H, MIRROR_SPARKLE_COMBO_W, MIRROR_SPARKLE_COMBO_CSET,
  348.             MIRROR_SPARKLE_COMBO_XSCALE, MIRROR_SPARKLE_COMBO_YSCALE, MIRROR_SPARKLE_COMBO_RX,
  349.             MIRROR_SPARKLE_COMBO_RY, MIRROR_SPARKLE_COMBO_RANGLE, Mirror[MIRROR_SPARKLE_COMBO_FRAME],
  350.             MIRROR_SPARKLE_COMBO_FLIP, true, MIRROR_SPARKLE_COMBO_OPACITY) ; //Mirror sparkle
  351.        
  352.         //Reduce the frames
  353.         if ( Mirror[MIRROR_SPARKLE_COMBO_FRAME] >= MIRROR_SPARKLE_COMBO_NUM_FRAMES ) Mirror[MIRROR_SPARKLE_COMBO_FRAME] = MIRROR_SPARKLE_COMBO_INIT_FRAME;
  354.         else Mirror[MIRROR_SPARKLE_COMBO_FRAME]++;
  355. }
  356.  
  357.  
  358. //Runs the moon pearl bunny sprite change, and halts using any item other than the mirror.
  359. void MoonPearl(){
  360.     if ( IsDarkWorld() && !Link->Item[I_MOONPEARL] && !Link->Item[I_BUNNYRING] ) Link->Item[I_BUNNYRING] = true;
  361.     if ( !IsDarkWorld() && Link->Item[I_BUNNYRING] ) Link->Item[I_BUNNYRING] = false;
  362.     if ( IsDarkWorld() && Link->Item[I_MOONPEARL] && Link->Item[I_BUNNYRING] ) Link->Item[I_BUNNYRING] = false;
  363.     if ( Link->Item[I_BUNNYRING] ) {
  364.         if ( Link->PressA && GetEquipmentA() != I_MIRROR ) Link->PressA = false;
  365.         if ( Link->PressB && GetEquipmentB() != I_MIRROR ) Link->PressB = false;
  366.     }
  367. }
  368.  
  369. /// Items
  370.  
  371. item script Mirror{
  372.     void run(){
  373.         if ( IsDungeonDMap() && MIRROR_RETURNS_TO_DUNGEON_ENTRANCE ) {
  374.             //Warp to dungeon entrance.
  375.             Game->PlaySound(SFX_WARP_DUNGEON);
  376.             Screen->Wavy = WARP_WAVE_DUR_DUNGEON;
  377.             Link->Warp(Game->GetCurDMap(), Game->DMapContinue[Game->GetCurDMap()]);
  378.         }
  379.         else {
  380.             if ( IsDarkWorld() ) {
  381.                 //SetPostWarpTimer();
  382.                 SetWarpReturn();
  383.                 IsWarping(true);
  384.             }
  385.             //Warp to other world
  386.             if ( !IsDarkWorld() && SFX_WARP_ERROR ) Game->PlaySound(SFX_WARP_ERROR);
  387.         }
  388.     }
  389. }
  390.  
  391. //Global Script Example
  392.  
  393. global script Z3_Mirror{
  394.     void run(){
  395.         while(true){
  396.             if ( REQUIRE_MOON_PEARL ) MoonPearl();
  397.             ReducePostWarpTimer();
  398.             MirrorWarpLink();
  399.  
  400.             //if ( TEST_MIRROR_SPARKLE ) TestSparkle();
  401.             //if ( MIRROR_SPARKLE_BEFORE_WAITDRAW ) MirrorSparkle();
  402.             Waitdraw();
  403.             WarpFinish();
  404.             //if ( !MIRROR_SPARKLE_BEFORE_WAITDRAW ) MirrorSparkle();
  405.             if ( WarpSparkle() ) MirrorSparkle(); //Call only if it exists.
  406.             Waitframe();
  407.         }
  408.     }
  409. }
  410.  
  411. //Deprecated
  412.  
  413. //bool TouchingSolid(int x, int y) {
  414.   //  if ( Screen->isSolid(x,y) ||
  415.   //  Screen->isSolid(x + SOLIDITY_CHECK_DISTANCE, y) ||
  416.   //  Screen->isSolid(x + SOLIDITY_CHECK_DISTANCE, y+SOLIDITY_CHECK_DISTANCE) ||
  417.   //  Screen->isSolid(x + SOLIDITY_CHECK_DISTANCE, y-SOLIDITY_CHECK_DISTANCE) ||
  418.   //  Screen->isSolid(x - SOLIDITY_CHECK_DISTANCE, y) ||
  419.   //  Screen->isSolid(x - SOLIDITY_CHECK_DISTANCE, y+SOLIDITY_CHECK_DISTANCE) ||
  420.   //  Screen->isSolid(x - SOLIDITY_CHECK_DISTANCE, y-SOLIDITY_CHECK_DISTANCE) ) {
  421.   //      return true;
  422.   //  }
  423.   //  else {
  424.    //     return false;
  425.   //  }
  426. //}
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement