Advertisement
ZoriaRPG

ZScript: Zelda 3 Style Mirror

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