Advertisement
ZoriaRPG

Zelda 3 Follower v0.6

Apr 10th, 2019
215
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 11.21 KB | None | 0 0
  1. /////////////////////////////
  2. /// Zelda 3 Follower      ///
  3. /// v0.6                  ///
  4. /// 10th April, 2019      ///
  5. /// By: ZoriaRPG          ///
  6. /// Made for: JudasRising ///
  7. /////////////////////////////
  8. // v0.1 : Initial
  9. // v0.2 : Changed hardcoded > 3 frame cap to use FOLLOWER_MAX_FRAME in drawing loops.
  10. // v0.3 : Fix scrolling positions and positions onContinue
  11. // v0.4 : The follower's tile is now set by the combo of the ffc 'GetZelda'. (It's combo tile, -4.)
  12. //      : Added the ability for the follower to play a message, and give an item to Link, when Link
  13. //      : delivers them to their destination.
  14. //  : Added the ability to show a message when you collect the npc.
  15. // v0.5 : The follower CSet is now set by the ffc when you collect him.
  16. // v0.6 : Renamed scripts and functions, and moved global functions into local functions of ffc script Follower.
  17.  
  18.  
  19. //Settings
  20. const int FOLLOWER_ZELDA_MIDI_DURATION  = 300;
  21. const int FOLLOWER_ZELDA_MIDI       = 1;
  22. const int FOLLOWER_MAX_FRAME        = 3; //4-frame walking animation
  23. //Binary flags for Screen->D
  24. const int FOLLOWER_SHOWED_MESSAGE   = 10b;
  25. const int FOLLOWER_GAVE_ITEM        = 1b;
  26.  
  27. //Array and array indices.
  28. int TheFollower[128] = {-1, -1};
  29.  
  30. const int FOLLOWER_MIDI_TIMER   = 0;
  31. const int FOLLOWER_RESCUED  = 1;
  32. const int FOLLOWER_ACTIVE   = 2;
  33. const int FOLLOWER_UPDATE   = 3;
  34. const int FOLLOWER_FRAME    = 4;
  35. const int FOLLOWER_SUBFRAME     = 5;
  36.  
  37. const int FOLLOWER_ORIG_MIDI    = 6;
  38. const int FOLLOWER_BASE_TILE    = 7;
  39. const int FOLLOWER_CSET     = 8;
  40.  
  41. const int FOLLOWER_X        = 10;
  42. const int FOLLOWER_X1       = 11;
  43. const int FOLLOWER_X2       = 12;
  44. const int FOLLOWER_X3       = 13;
  45. const int FOLLOWER_X4       = 14;
  46. const int FOLLOWER_X5       = 15;
  47. const int FOLLOWER_X6       = 16;
  48. const int FOLLOWER_X7       = 17;
  49. const int FOLLOWER_X8       = 19;
  50. const int FOLLOWER_X9       = 20;
  51. const int FOLLOWER_X10      = 21;
  52. const int FOLLOWER_X11      = 22;
  53. const int FOLLOWER_X12      = 23;
  54. const int FOLLOWER_X13      = 23;
  55. const int FOLLOWER_X14      = 24;
  56. const int FOLLOWER_X15      = 26;
  57. const int FOLLOWER_X16      = 27;
  58. const int FOLLOWER_X17      = 28;
  59. const int FOLLOWER_X18      = 29;
  60. const int FOLLOWER_X19      = 30;
  61. const int FOLLOWER_X20      = 31;
  62.  
  63. const int FOLLOWER_Y        = 40;
  64. const int FOLLOWER_Y1       = 41;
  65. const int FOLLOWER_Y2       = 42;
  66. const int FOLLOWER_Y3       = 43;
  67. const int FOLLOWER_Y4       = 44;
  68. const int FOLLOWER_Y5       = 45;
  69. const int FOLLOWER_Y6       = 46;
  70. const int FOLLOWER_Y7       = 47;
  71. const int FOLLOWER_Y8       = 48;
  72. const int FOLLOWER_Y9       = 49;
  73. const int FOLLOWER_Y10      = 50;
  74. const int FOLLOWER_Y11      = 51;
  75. const int FOLLOWER_Y12      = 52;
  76. const int FOLLOWER_Y13      = 53;
  77. const int FOLLOWER_Y14      = 54;
  78. const int FOLLOWER_Y15      = 55;
  79. const int FOLLOWER_Y16      = 56;
  80. const int FOLLOWER_Y17      = 57;
  81. const int FOLLOWER_Y18      = 58;
  82. const int FOLLOWER_Y19      = 59;
  83. const int FOLLOWER_Y20      = 60;
  84.  
  85. const int FOLLOWER_DIR      = 70;
  86. const int FOLLOWER_DIR1     = 71;
  87. const int FOLLOWER_DIR2     = 72;
  88. const int FOLLOWER_DIR3     = 73;
  89. const int FOLLOWER_DIR4     = 74;
  90. const int FOLLOWER_DIR5     = 75;
  91. const int FOLLOWER_DIR6     = 76;
  92. const int FOLLOWER_DIR7     = 77;
  93. const int FOLLOWER_DIR8     = 78;
  94. const int FOLLOWER_DIR9     = 79;
  95. const int FOLLOWER_DIR10    = 80;
  96. const int FOLLOWER_DIR11    = 81;
  97. const int FOLLOWER_DIR12    = 82;
  98. const int FOLLOWER_DIR13    = 83;
  99. const int FOLLOWER_DIR14    = 84;
  100. const int FOLLOWER_DIR15    = 85;
  101. const int FOLLOWER_DIR16    = 86;
  102. const int FOLLOWER_DIR17    = 87;
  103. const int FOLLOWER_DIR18    = 88;
  104. const int FOLLOWER_DIR19    = 89;
  105. const int FOLLOWER_DIR20    = 90;
  106.  
  107. // When Link collides with this ffc, it triggers the follower.
  108. //
  109. // When you use this, add a second ffc on the screen with the combo of the follower, and then
  110. // set the Link property of the ffc running the script to the ffc ID of the second ffc.
  111. //
  112. // The second, linked ffc is used to draw the follower until you collect them, and it also sets
  113. // both the tiles to draw, and the CSet to use when drawing the follower.
  114. //
  115. // You can Link this to itself, but then Link will need to walk onto the follower image to 'collect' them.
  116. ffc script Follower
  117. {
  118.     void run(int sfx, int msg)
  119.     {
  120.         ffc f = Screen->LoadFFC(this->Link);
  121.         while(1)
  122.         {
  123.             if ( Collision(this) && TheFollower[FOLLOWER_RESCUED] < 0)
  124.             {
  125.                 //f->Data = 0;
  126.                 TheFollower[FOLLOWER_RESCUED] = 2;
  127.                 Game->PlaySound(sfx);
  128.                 TheFollower[FOLLOWER_BASE_TILE] = Game->ComboTile(f->Data)-4;
  129.                 TheFollower[FOLLOWER_CSET] = f->CSet;
  130.                 if ( msg ) Screen->Message(msg);
  131.                
  132.                 //break;//Quit();
  133.             }
  134.             if ( TheFollower[FOLLOWER_ACTIVE] > 15 )
  135.             {
  136.                 f->Data = 0;
  137.             }
  138.             Waitframe();
  139.         }
  140.     }
  141.     void wait(int num, int x, int y, int til)
  142.     {
  143.         for (; num >= 0; --num)
  144.         {
  145.             Screen->FastTile(2, x, y, til, TheFollower[FOLLOWER_CSET], 128 );
  146.             Waitframe();
  147.         }
  148.     }
  149.     //Returns true if the player is holding, or pressed a directional key or button.
  150.     bool pressedDPad()
  151.     {
  152.         if ( Link->InputUp ) return true;
  153.         if ( Link->InputDown ) return true;
  154.         if ( Link->InputLeft ) return true;
  155.         if ( Link->InputRight ) return true;
  156.         if ( Link->PressUp ) return true;
  157.         if ( Link->PressDown ) return true;
  158.         if ( Link->PressLeft ) return true;
  159.         if ( Link->PressRight ) return true;
  160.         if ( Link->InputAxisUp ) return true;
  161.         if ( Link->InputAxisDown ) return true;
  162.         if ( Link->InputAxisLeft ) return true;
  163.         if ( Link->InputAxisRight ) return true;
  164.         if ( Link->PressAxisUp ) return true;
  165.         if ( Link->PressAxisDown ) return true;
  166.         if ( Link->PressAxisLeft ) return true;
  167.         if ( Link->PressAxisRight ) return true;
  168.         return false;
  169.     }
  170.     //Zelda follows in Link's path with an 8 frame delay before updating
  171.     void draw()
  172.     {
  173.         if ( !TheFollower[FOLLOWER_ACTIVE] ) return;
  174.         if ( pressedDPad() )
  175.         {
  176.             ++TheFollower[FOLLOWER_ACTIVE];
  177.             if ( TheFollower[FOLLOWER_ACTIVE] > 100000 ) TheFollower[FOLLOWER_ACTIVE] = 8; //Don't roll over
  178.            
  179.         }
  180.        
  181.        
  182.            
  183.         if ( Link->Action == LA_GOTHURTLAND ) return; //Don't update if Link was hurt and pushed back.
  184.  
  185.         if ( pressedDPad() )
  186.         {
  187.             ++TheFollower[FOLLOWER_SUBFRAME];
  188.             if ( TheFollower[FOLLOWER_SUBFRAME]&1 )
  189.             {
  190.                 ++TheFollower[FOLLOWER_FRAME];
  191.                 if ( TheFollower[FOLLOWER_FRAME] > FOLLOWER_MAX_FRAME ) TheFollower[FOLLOWER_FRAME] = 0;
  192.             }
  193.            
  194.             TheFollower[FOLLOWER_X] = Link->X;
  195.             TheFollower[FOLLOWER_Y] = Link->Y;
  196.             TheFollower[FOLLOWER_DIR] = Link->Dir;
  197.             for ( int q = FOLLOWER_X12; q >= FOLLOWER_X; --q )
  198.             {
  199.                 TheFollower[q] = TheFollower[q-1];
  200.             }
  201.             for ( int q = FOLLOWER_Y12; q >= FOLLOWER_Y; --q )
  202.             {
  203.                 TheFollower[q] = TheFollower[q-1];
  204.             }
  205.             for ( int q = FOLLOWER_DIR12; q >= FOLLOWER_DIR; --q )
  206.             {
  207.                 TheFollower[q] = TheFollower[q-1];
  208.             }
  209.        
  210.         }
  211.         if ( TheFollower[FOLLOWER_ACTIVE] < 16 ) return; //Wait 8 frames to begin.
  212.         //Draw tiles
  213.         int the_tile;
  214.          
  215.         the_tile = TheFollower[FOLLOWER_BASE_TILE] + (TheFollower[FOLLOWER_DIR12]*4) + TheFollower[FOLLOWER_FRAME];
  216.         //Based on X, Y, Dir and Frame
  217.         Screen->FastTile(2, TheFollower[FOLLOWER_X12], TheFollower[FOLLOWER_Y12],
  218.                     the_tile, TheFollower[FOLLOWER_CSET], 128 );
  219.        
  220.        
  221.         //...then Update the frame
  222.        
  223.     }
  224.    
  225.    
  226.     //Called to initialise the follower.
  227.     void rescue(int follower_midi, int dur)
  228.     {
  229.         if ( TheFollower[FOLLOWER_RESCUED] < 2 ) return;
  230.        
  231.         --TheFollower[FOLLOWER_RESCUED];
  232.         if ( !dur ) dur = FOLLOWER_ZELDA_MIDI_DURATION;
  233.         if ( !follower_midi ) follower_midi = FOLLOWER_ZELDA_MIDI;
  234.         TheFollower[FOLLOWER_ACTIVE] = 1;
  235.         if ( TheFollower[FOLLOWER_MIDI_TIMER] == -1 )
  236.         {
  237.            
  238.             TheFollower[FOLLOWER_ORIG_MIDI] = Game->DMapMIDI[Game->GetCurDMap()];
  239.             TheFollower[FOLLOWER_MIDI_TIMER] = dur;
  240.             Game->PlayMIDI(follower_midi);
  241.         }
  242.         else
  243.         {
  244.             --TheFollower[FOLLOWER_MIDI_TIMER];
  245.             if ( TheFollower[FOLLOWER_MIDI_TIMER] < 1 )
  246.             {
  247.                 Game->PlayMIDI(TheFollower[FOLLOWER_ORIG_MIDI]);
  248.                 TheFollower[FOLLOWER_MIDI_TIMER] = 0;
  249.             }
  250.         }
  251.  
  252.     }  
  253.  
  254.     // Clears the follower positions if Link dies, if the playe presses F6, and so forth.
  255.     // Called in active, continue, and exit scripts.
  256.     // Use in Link's Init script if using 2.55.
  257.     void clear()
  258.     {
  259.         for ( int q = FOLLOWER_X; q <= FOLLOWER_X20; ++q )
  260.         {
  261.             TheFollower[q] = Link->X;
  262.         }
  263.         for ( int q = FOLLOWER_Y; q <= FOLLOWER_Y20; ++q )
  264.         {
  265.             TheFollower[q] = Link->Y;
  266.         }
  267.         for ( int q = FOLLOWER_DIR; q <= FOLLOWER_DIR20; ++q )
  268.         {
  269.             TheFollower[q] = Link->Dir;
  270.         }
  271.     }
  272.  
  273.     // Called in the active script during scrolling to prevent the follower from drawing at the wrong position.
  274.     void scroll()
  275.     {
  276.         if ( Link->Action != LA_SCROLLING ) return;
  277.         for ( int q = FOLLOWER_X; q <= FOLLOWER_X20; ++q )
  278.         {
  279.             TheFollower[q] = Link->X;
  280.         }
  281.         for ( int q = FOLLOWER_Y; q <= FOLLOWER_Y20; ++q )
  282.         {
  283.             TheFollower[q] = Link->Y;
  284.         }
  285.         for ( int q = FOLLOWER_DIR; q <= FOLLOWER_DIR20; ++q )
  286.         {
  287.             TheFollower[q] = Link->Dir;
  288.         }
  289.     }
  290. }
  291.  
  292.  
  293. const int FOLLOWER_REGISTER = 1;
  294.  
  295. ffc script LeaveFollower
  296. {
  297.     void run(int msg, int itm)
  298.     {
  299.         this->Data = CMB_INVISIBLE;
  300.         //bool matched = false;
  301.         //if ( TheFollower[FOLLOWER_ACTIVE] ) this->Data = CMB_INVISIBLE;
  302.         if ( TheFollower[FOLLOWER_ACTIVE] ) TheFollower[FOLLOWER_ACTIVE] = 0;
  303.         //else ;
  304.         int the_tile; bool playedmsg = false;
  305.        
  306.         while ( 1 ) //TheFollower[FOLLOWER_X12] != this->X && TheFollower[FOLLOWER_Y12] != this->Y )
  307.         {
  308.             if ( TheFollower[FOLLOWER_X12] < this->X ) { ++TheFollower[FOLLOWER_X12]; TheFollower[FOLLOWER_DIR12] = DIR_RIGHT; }
  309.             if ( TheFollower[FOLLOWER_X12] > this->X ) { --TheFollower[FOLLOWER_X12]; TheFollower[FOLLOWER_DIR12] = DIR_LEFT; }
  310.            
  311.             if ( TheFollower[FOLLOWER_Y12] < this->Y ) { ++TheFollower[FOLLOWER_Y12]; TheFollower[FOLLOWER_DIR12] = DIR_DOWN; }
  312.             if ( TheFollower[FOLLOWER_Y12] > this->Y ) { --TheFollower[FOLLOWER_Y12]; TheFollower[FOLLOWER_DIR12] = DIR_UP; }
  313.             ++TheFollower[FOLLOWER_FRAME];
  314.             if ( TheFollower[FOLLOWER_FRAME] > FOLLOWER_MAX_FRAME ) TheFollower[FOLLOWER_FRAME] = 0;
  315.             the_tile = TheFollower[FOLLOWER_BASE_TILE] + (TheFollower[FOLLOWER_DIR12]*4) + TheFollower[FOLLOWER_FRAME];
  316.             if ( TheFollower[FOLLOWER_X12] == this->X && TheFollower[FOLLOWER_Y12] == this->Y ) { TheFollower[FOLLOWER_DIR12] = DIR_DOWN; TheFollower[FOLLOWER_FRAME] = 0; }
  317.             Follower.wait(2,TheFollower[FOLLOWER_X12],TheFollower[FOLLOWER_Y12],the_tile);
  318.             if ( TheFollower[FOLLOWER_X12] == this->X )
  319.             {
  320.                 if ( TheFollower[FOLLOWER_Y12] == this->Y )
  321.                 {
  322.                     if ( msg )
  323.                     {
  324.                         if ( !(Screen->D[FOLLOWER_REGISTER]&FOLLOWER_SHOWED_MESSAGE) )
  325.                         {
  326.                            
  327.                            
  328.                             Screen->D[FOLLOWER_REGISTER] |= FOLLOWER_SHOWED_MESSAGE;
  329.                             Screen->Message(msg);
  330.                         }
  331.                     }
  332.                     if ( itm )
  333.                     {
  334.                         if ( !(Screen->D[FOLLOWER_REGISTER]&FOLLOWER_GAVE_ITEM) )
  335.                         {
  336.                            
  337.                            
  338.                             Screen->D[FOLLOWER_REGISTER] |= FOLLOWER_GAVE_ITEM;
  339.                             item giveit = Screen->CreateItem(itm);
  340.                             giveit->X = Link->X;
  341.                             giveit->Y = Link->Y;
  342.                             giveit->Pickup = IP_HOLDUP;
  343.                            
  344.                         }
  345.                     }
  346.                 }
  347.             }
  348.         }
  349.        
  350.     }
  351.    
  352. }
  353.  
  354. //Example global script.
  355. global script FollowerActive
  356. {
  357.     void run()
  358.     {
  359.         Follower.clear();
  360.         while(1)
  361.         {
  362.             Follower.rescue(FOLLOWER_ZELDA_MIDI, FOLLOWER_ZELDA_MIDI_DURATION);
  363.             Follower.draw();
  364.             Follower.scroll();
  365.             Waitdraw();
  366.             Waitframe();
  367.         }
  368.     }
  369. }
  370.  
  371.  
  372.  
  373.  
  374.  
  375. global script FollowerResume
  376. {
  377.     void run()
  378.     {
  379.         //int ss[]="Running onContinue";
  380.         //TraceS(ss);
  381.         Follower.clear();
  382.     }
  383. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement