Advertisement
ZoriaRPG

Cane of Somaria v0.4.1 (12-NOV-2016)

Nov 7th, 2016
239
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 28.64 KB | None | 0 0
  1. ///////////////////////
  2. /// Cane of Somaria ///
  3. /// v0.4.1          ///
  4. /// 12-NOV-2016     ///
  5. /// By: ZoriaRPG    ///
  6. ///////////////////////////
  7. /// Created for TeamUDF ///
  8. ///////////////////////////
  9.  
  10. //! Platform code
  11.  
  12. const int I_SOMARIA_BLOCK = 200; //When a somaria block ffc is on a conveyor, generatethis and key the ffc x/y
  13.                 // coordinates to the item, so that the block uses engine onveyor movement
  14.                 //The item should use a blank tile, and thus, be invisible.
  15.  
  16. const int I_SOMARIA_MISC = 0;
  17. const int I_FLAG_SOMARIA_ON_CONVEYOR = 01b;
  18.  
  19. const int CMB_SOMARIA_PLATFORM_INACTIVE = 100; //the '?' combo
  20.  
  21. const int LWEAPON_MISC_ID = 8; //l->Misc[] holds the ID of the weapon.
  22. const int LWT_SOMARIA = 100; //Attribute for somaria objects.
  23.  
  24. const int STORE_FFC_DATA = 0;
  25. const int STORE_FFC_SCRIPT = 1;
  26. const int STORE_FFC_CSET = 2;
  27. const int STORE_FFC_DELAY = 3;
  28. const int STORE_FFC_X = 4;
  29. const int STORE_FFC_Y = 5;
  30. const int STORE_FFC_VX = 6;
  31. const int STORE_FFC_VY = 7;
  32. const int STORE_FFC_AX = 8;
  33. const int STORE_FFC_AY = 9;
  34. const int STORE_FFC_TILEWIDTH = 10;
  35. const int STORE_FFC_TILEHEIGHT = 11;
  36. const int STORE_FFC_EFFECTWIDTH = 12;
  37. const int STORE_FFC_EFFECTHEIGHT = 13;
  38. const int STORE_FFC_LINK = 14;
  39.  
  40. const int STORE_FFC_FLAGS_MIN = 15;
  41. const int STORE_FFC_FLAGS_MAX = 24;
  42.  
  43. const int STORE_FFC_FLAGS_0 = 15;
  44. const int STORE_FFC_FLAGS_1 = 16;
  45. const int STORE_FFC_FLAGS_2 = 17;
  46. const int STORE_FFC_FLAGS_3 = 18;
  47. const int STORE_FFC_FLAGS_4 = 19;
  48. const int STORE_FFC_FLAGS_5 = 20;
  49. const int STORE_FFC_FLAGS_6 = 21;
  50. const int STORE_FFC_FLAGS_7 = 22;
  51. const int STORE_FFC_FLAGS_8 = 23;
  52. const int STORE_FFC_FLAGS_9 = 24;
  53.  
  54. const int STORE_FFC_MISC_MIN = 25;
  55. const int STORE_FFC_MISC_MAX = 39;
  56.  
  57. const int STORE_FFC_MISC_0 = 25;
  58. const int STORE_FFC_MISC_1 = 26;
  59. const int STORE_FFC_MISC_2 = 27;
  60. const int STORE_FFC_MISC_3 = 28;
  61. const int STORE_FFC_MISC_4 = 29;
  62. const int STORE_FFC_MISC_5 = 30;
  63. const int STORE_FFC_MISC_6 = 31;
  64. const int STORE_FFC_MISC_7 = 32;
  65. const int STORE_FFC_MISC_8 = 33;
  66. const int STORE_FFC_MISC_9 = 34;
  67. const int STORE_FFC_MISC_10 = 35;
  68. const int STORE_FFC_MISC_11 = 36;
  69. const int STORE_FFC_MISC_12 = 37;
  70. const int STORE_FFC_MISC_13 = 38;
  71. const int STORE_FFC_MISC_14 = 39;
  72.  
  73. void StoreSomariaPlatform(ffc this, int arr){
  74.     int q;
  75.     arr[STORE_FFC_DATA] = this->Data;
  76.     arr[STORE_FFC_SCRIPT] = this->Script;
  77.     arr[STORE_FFC_CSET] = this->CSet;
  78.     arr[STORE_FFC_DELAY] = this->Delay;
  79.     arr[STORE_FFC_X] = this->X;
  80.     arr[STORE_FFC_Y] = this->Y;
  81.     arr[STORE_FFC_VX] = this->Vx;
  82.     arr[STORE_FFC_VY] = this->Vy;
  83.     arr[STORE_FFC_AX] = this->Ax;
  84.     arr[STORE_FFC_AY] = this->Ay;
  85.     for ( q = 0; q < 10; q++ ) arr[STORE_FFC_FLAGS_MIN] + q = this->Flags[q];
  86.     arr[STORE_FFC_TILEWIDTH] = this->TileWidth;
  87.     arr[STORE_FFC_TILEHEIGHT] = this->TileWidth;
  88.     arr[STORE_FFC_EFFECTWIDTH] = this->EffectWidth;
  89.     arr[STORE_FFC_EFFECTHEIGHT] = this->EffectHeight;
  90.     arr[STORE_FFC_LINK] = this->Link;
  91.     for ( q = 0; q < 15; q++ ) arr[STORE_FFC_MISC_MIN] + q = this->Misc[q];
  92. }
  93.  
  94. void RestoreSomariaPlatform(ffc this, int arr){
  95.     int q;
  96.     this->Data = arr[STORE_FFC_DATA];
  97.     this->Script = arr[STORE_FFC_SCRIPT];
  98.     this->CSet = arr[STORE_FFC_CSET];
  99.     this->Delay = arr[STORE_FFC_DELAY];
  100.     this->X = arr[STORE_FFC_X];
  101.     this->Y = arr[STORE_FFC_Y];
  102.     this->Vx = arr[STORE_FFC_VX];
  103.     this->Vy = arr[STORE_FFC_VY];
  104.     this->Ax = arr[STORE_FFC_AX];
  105.     this->Ay = arr[STORE_FFC_AY];
  106.     for ( q = 0; q < 10; q++ ) this->Flags[q] = arr[STORE_FFC_FLAGS_MIN] + q;
  107.     this->TileWidth = arr[STORE_FFC_TILEWIDTH];
  108.     this->TileWidth = arr[STORE_FFC_TILEHEIGHT];
  109.     this->EffectWidth = arr[STORE_FFC_EFFECTWIDTH];
  110.     this->EffectHeight = arr[STORE_FFC_EFFECTHEIGHT];
  111.     this->Link = arr[STORE_FFC_LINK];
  112.     for ( q = 0; q < 15; q++ ) this->Misc[q] = arr[STORE_FFC_MISC_MIN] + q;
  113. }
  114.  
  115. const int SOMARIA_PLATFORM_MOVE_COMBO_LAYER = 4;
  116. const int SOMARIA_PLATFORM_MOVE_COMBO_LEFT = 1000;
  117. const int SOMARIA_PLATFORM_MOVE_COMBO_RIGHT = 1001;
  118. const int SOMARIA_PLATFORM_MOVE_COMBO_UP = 1002;
  119. const int SOMARIA_PLATFORM_MOVE_COMBO_DOWN = 1003;
  120. const int SOMARIA_PLATFORM_MOVE_COMBO_STOP = 1004;
  121.  
  122. //**** TO DO ****
  123.  
  124. //! We need to make platforms flobal, so that they continue to exist between screen transitions.
  125. //! To do this, the drawn effect, and the conditions that determine if Link is on a platform, and thus
  126. //! unaffected by pits, will need to be global.
  127. //! Further. the actual platform visuals will need to be drawn globally.
  128. //! On-screen movement of the platform, following a combo path, can still be an ffc.
  129.  
  130. //! The tiles need to be CENTRED on the path, not bound to it at precise XY. This requires an offset
  131. //! for each axis.
  132.  
  133. //! The player will need to be able to choose from branching paths. Thus, while on the platform, Link
  134. //! should not be able to move, but he should be able to change direction.
  135. //! Pressing U/D/L/R should change his facing direction, and if on a path branch, change the path.
  136. //! Only when the platform reaches a new [?] combo, should he be able to walk off.
  137.  
  138. //! Link should be able to use all items while on the platform, although jumping may be broken.
  139.  
  140. //! We need to use a global condition, 'GRAM[ON_SOMARIA_PLATFORM]' to denote that Link can sail over pits.
  141. //! We can use this, without setting his Z-axis or anything else. This will be far more reliable, although
  142. //! for bomb jumping, off the platform, we may need to set his Z-axis.
  143.  
  144. //! We need to prevent Link from being knocked back while on the Somaria platform.
  145.  
  146. //Run on screen init.
  147. ffc script SomariaPlaform{
  148.     void run(){
  149.        
  150.        
  151.         bool inactive = true;
  152.         int a[255]; lweapon l; ffc f; //f holds platform settings.
  153.         int platform[40];
  154.         //we need void BackupFFC(ffc f, int arr) and RestoreFFC(int arr, ffc f)
  155.         StoreSomariaPlatform(this, a);
  156.         while(true){
  157.             while(inactive) {
  158.                 this->Vx = 0;
  159.                 this->Vy = 0;
  160.                 this->Ax = 0;
  161.                 this->Ay = 0;
  162.                 this->Data = CMB_SOMARIA_PLATFORM_INACTIVE;
  163.                 this->EffectWidth = 16;
  164.                 this->EffectHeight = 16;
  165.                 this->TileWidth = 1;
  166.                 this->TileHeight = 1;
  167.                 this->Effect
  168.                 for ( a[254] = Screen->NumLWeapons(); a[254] > 0; a[254]-- ) { //optimised v0.4
  169.                     l = Screen->LoadLWeapon(a[254]);
  170.                     if ( l->Misc[LWEAPON_MISC_ID] == LWT_SOMARIA ) {
  171.                         if ( Collision(l,this) ) inactive = false;
  172.                     }
  173.                 }
  174.                 Waitframe();
  175.             }
  176.             RestoreSomariaPlatform(this,a); //Restore the movement params, and the graphics, and size.
  177.             for ( q[254] = 0; q[254] < 176; q[254]++ ) {
  178.                 //Check collisions with combos on layer N for movement changes.
  179.                 if ( GetLayerComboD(SOMARIA_PLATFORM_MOVE_COMBO_LAYER, q[254]) == SOMARIA_PLATFORM_MOVE_COMBO_LEFT )  {
  180.                     if ( Collision(this, cmb) {
  181.                         //This Collision() may be too sensitive.
  182.                         //Change movement to leftward.
  183.                     }
  184.                 }
  185.                 if ( GetLayerComboD(SOMARIA_PLATFORM_MOVE_COMBO_LAYER, q[254]) == SOMARIA_PLATFORM_MOVE_COMBO_RIGHT )  {
  186.                     if ( Collision(this, cmb) {
  187.                         //This Collision() may be too sensitive.
  188.                         //Change movement to rightward.
  189.                     }
  190.                 }
  191.                 if ( GetLayerComboD(SOMARIA_PLATFORM_MOVE_COMBO_LAYER, q[254]) == SOMARIA_PLATFORM_MOVE_COMBO_UP )  {
  192.                     if ( Collision(this, cmb) {
  193.                         //This Collision() may be too sensitive.
  194.                         //Change movement to upwward.
  195.                     }
  196.                 }
  197.                 if ( GetLayerComboD(SOMARIA_PLATFORM_MOVE_COMBO_LAYER, q[254]) == SOMARIA_PLATFORM_MOVE_COMBO_DOWN )  {
  198.                     if ( Collision(this, cmb) {
  199.                         //This Collision() may be too sensitive.
  200.                         //Change movement to downward.
  201.                     }
  202.                 }
  203.                 if ( GetLayerComboD(SOMARIA_PLATFORM_MOVE_COMBO_LAYER, q[254]) == SOMARIA_PLATFORM_MOVE_COMBO_STOP )  {
  204.                     if ( Collision(this, cmb) {
  205.                         //This Collision() may be too sensitive.
  206.                         //Halt all movement
  207.                         this->Vx = 0;
  208.                         this->Vy = 0;
  209.                         this->Ax = 0;
  210.                         this->Ay = 0;
  211.                     }
  212.                 }
  213.                
  214.                
  215.             }
  216.             //If Link is on the playform
  217.             if ( Collision(this) ) {
  218.                 //Move Link with the platform
  219.                 if ( !Link->Misc[ON_PLATFORM] ) Link->Misc[ON_PLATFORM = 1];
  220.                 Link->Z = 1;
  221.                 //...and keep his Z at 1 to pass over pits, unharmed.
  222.                
  223.                 //Store that Link is on a platform in Link->Misc[]
  224.                 //...we'll use that to ensure that we make a new platform under him, after screen transitions / during scrolling
  225.             }
  226.            
  227.             //If Link walks off the platform onto a pit...he shouldn;t keep falling in mid-air.
  228.             //We need to prevent that.
  229.            
  230.             //Stop reporting being on a platform, if Link isn't riding.
  231.             if ( !Collision(this) && Link->Misc[ON_PLATFORM] ) Link->Misc[ON_PLATFORM] = 0;
  232.            
  233.             Waitframe();
  234.         }
  235.     }
  236. }
  237.  
  238.  
  239. const int PITS_GRACE_WHEN_INJURED = 1; //If Link is hurt, he won;t fall down a pit. Good for bomb jumping, bad for other things.
  240. const int PITS_ALLOW_BOMB_JUMPING = 1; //More precise for bomb jumping.
  241.  
  242.    
  243.    
  244. ffc script Pit{
  245.     void run(int respawn_screen_init){
  246.         int a[256]; bool falling; bool pit; bool onpitedge;
  247.        
  248.         Waitframes(5);
  249.        
  250.         //Store where Link was on screen init:
  251.         a[50] = Link->X; a[51] = Link->Y;
  252.        
  253.         while(true){
  254.             if ( !falling && !onpitedge && !Link->Misc[ON_PLATFORM] ) { a[10] = Link->X; a[11] = Link->Y; }
  255.             if ( falling ) { a[12] = a[10]; a[13] = a[11]; }
  256.             //Store Link's X/Y in the array, so that we have a respawn location.
  257.             //Find combos with a type of HOOKSHOT_ONLY and an Inherent Flag of CI_PIT.
  258.             for ( a[0] = 0; a[0] < 176; a[0]++ ) {
  259.                 if ( ComboT[a[0]] == CT_HOOKSHOT || ComboT[a[0]] == CT_LADDER || ComboT[a[0]] == CT_LADDERHOOKSHOT || ComboI[a[0]] == CT_PIT ) {
  260.                     if ( DistX(a[0],14) && DistY(a[0],14) && !DistY(a[0],9) && !DistX(a[0],9) ) onpitedge = true;
  261.                     else onpitedge = false;
  262.                     if ( DistX(a[0],8) && DistY(a[0],8) {
  263.                         if ( !NumLWeaponsOf(LW_HOOKSHOT) ) {
  264.                             if ( Link->Z <= 0 && !Link->Jump ) {
  265.                                 falling = true;
  266.                             }
  267.                         }
  268.                     }
  269.                 }
  270.             }
  271.            
  272.                
  273.             if ( falling ) {
  274.                 NoAction();
  275.                
  276.                 Link->X = ComboX(a[0]); Link->Y = ComboY(a[0]);
  277.                
  278.                 a[4] = ComboX(a[0]); a[5] = ComboY(a[0]);
  279.                 a[8] = 16; //Scale
  280.                 //Waitframe(); //Not needed if we're going it after Waitdraw()
  281.                 a[20] = Link->Tile; //Set before hs becomes invisible and this value turns to shyte.
  282.                
  283.                 // We need to avoid storing this if the new location is a platform.  This is important, primarily
  284.                 //because he can walk off the edge of a platform manually, and he'd fall in an endless loop.
  285.                
  286.                 //This might mean that either the platform ffc needs higher priority than this, so that the Link->Misc
  287.                 //value is set, or that we need to check if he is on a platform in the pits ffc, too.
  288.                
  289.                
  290.                
  291.                 if ( !effects ) {
  292.                     effects = true;
  293.                     Game->PlaySound(SFX_FALL_PIT);
  294.                     Link->HP -= PIT_DAMAGE;
  295.                 }
  296.                 for ( a[1] = 0; a[1] < PIT_FALLING_ANIM_DUR; a[1]++ ) {
  297.                     Screen_>DrawTile(2, a[4]; a[5]; a[20]; ... scale=a[8], ... true, OP_OPAQUE);
  298.                     if ( a[1] % 10 == 0 && a[8] > 0 ) a[8]--; //Trim the scale.
  299.                     Waitframe();
  300.                 }
  301.                 Waitframes(5);
  302.                 //Spawn Link Again
  303.                 for ( a[1] = 0; a[1] < PIT_RESPAWN_LINK_DUR; a[1]++ ) {
  304.                     if ( !respawn_screen_init )
  305.                         Link->X = a[12]; Link->Y = a[13];
  306.                     if ( respawn_screen_init )
  307.                         //If d0 is set, we read a[50] and a[51] for the values to use when respawning him.
  308.                         Link->X = a[50]; Link->Y = a[51];
  309.                     if ( a[1] % 4 != 0 ) Link->Invisible = true;
  310.                     else Link->Invisible = false;
  311.                     Waitframe();
  312.                 }
  313.                 falling = false;
  314.                 effects = false;
  315.                     //Freeze Link
  316.                     //Store his x/y
  317.                     //Center the x/y over the combo
  318.                     //Make Link invisible,
  319.                     //Draw his tile in a loop, growing smaller
  320.                     //Play falling sound
  321.                     //hurt him
  322.                     //Wait a few frames
  323.                     //Spawn him
  324.                     //make him flicker by using a for loop, in which at % == 0 he is visible, and ! % == 0 he is invisible
  325.                         //for 30 frames, during which his collision is off.
  326.                 }
  327.             Waitframe();
  328.         }
  329.     }
  330. }
  331.  
  332.  
  333. //! Somaria Blocks
  334.  
  335. const int CMB_SOMARIA = 1000;
  336. const int TILE_SOMARIA = 10000;
  337. const int SPRITE_SOMARIA = 100;
  338.  
  339. const int SFX_SOMARIA_BEAMS = 63;
  340.  
  341. const int CMB_MOVING_COMARIA_D = 1001;  //4-way push
  342. const int CMB_MOVING_SOMARIA_C = 0; //CSet
  343. const int CMB_MOVING_SOMARIA_T = ;
  344. const int CMB_MOVING_SOMARIA_S = 4;
  345. const int CMB_MOVING_SOMARIA_F = ;
  346. const int CMB_MOVING_SOMARIA_I = ;
  347.  
  348. const int SPRITE_SOMARIA_BEAM = 101;
  349.  
  350. const int SOMARIA_BEAM_BASEPOWER = 8;
  351.  
  352.  
  353. int Somaria[214747];
  354. const int SOMARIA_NEWBLOCK_OLDCOMBO = 0;
  355. const int SOMARIA_NEWBLOCK_OLDCOMBO_D = 1;
  356. const int SOMARIA_NEWBLOCK_OLDCOMBO_T = 2;
  357. const int SOMARIA_NEWBLOCK_OLDCOMBO_C = 3;
  358. const int SOMARIA_NEWBLOCK_OLDCOMBO_S = 4;
  359. const int SOMARIA_NEWBLOCK_OLDCOMBO_F = 5;
  360. const int SOMARIA_NEWBLOCK_OLDCOMBO_I = 6;
  361.  
  362.  
  363. const int SOMARIA_NEWBLOCK_NEWCOMBO = 7;
  364. const int SOMARIA_NEWBLOCK_NEWCOMBO_D = 8;
  365. const int SOMARIA_NEWBLOCK_NEWCOMBO_T = 9;
  366. const int SOMARIA_NEWBLOCK_NEWCOMBO_C = 10;
  367. const int SOMARIA_NEWBLOCK_NEWCOMBO_S = 11;
  368. const int SOMARIA_NEWBLOCK_NEWCOMBO_F = 12;
  369. const int SOMARIA_NEWBLOCK_NEWCOMBO_I = 13;
  370.  
  371. const int SOMARIA_BLOCK_EXISTS = 100;
  372. const int SOMARIA_BEAM_POWER = 200;
  373.  
  374. void SetSomariaBeamPower(int power){
  375.     Somaria[SOMARIA_BEAM_POWER] = power;
  376. }
  377. int GetSomariaBeamPower(){ return Somaria[SOMARIA_BEAM_POWER];}
  378.  
  379. const int TILE_LINK_LIFT_UP = 0;
  380. const int TILE_LINK_LIFT_DOWN = 0;
  381. const int TILE_LINK_LIFT_LEFT = 0;
  382. const int TILE_LINK_LIFT_RIGHT = 0;
  383. const int SOMARIA_OVERHEAD_OFFSET_X_UP = 0;
  384. const int SOMARIA_OVERHEAD_OFFSET_X_DOWN = 0;
  385. const int SOMARIA_OVERHEAD_OFFSET_X_LEFT = 0;
  386. const int SOMARIA_OVERHEAD_OFFSET_X_RIGHT = 0;
  387. const int SOMARIA_OVERHEAD_OFFSET_Y_UP = 0;
  388. const int SOMARIA_OVERHEAD_OFFSET_Y_DOWN = 0;
  389. const int SOMARIA_OVERHEAD_OFFSET_Y_LEFT = 0;
  390. const int SOMARIA_OVERHEAD_OFFSET_Y_RIGHT = 0;
  391.  
  392. const int LW_SOMARIA = 0; //Probably a script type.
  393. const int LW_SOMARIA_BEAM = 0; //Probably the same as swordbeams.
  394. const int LW_SOMARIA_FLAME = 0; //If we also want to double the somaria beam so that it acts as fire.
  395.  
  396. const int SOMARIA_BEAMS_COUNT_AS_FIRE = 1; //A setting to make somaria beams also count as fire weapons.
  397. const int SOMARIA_BEAMS_SET_OFF_BOMBS = 1; //What it says on the tin.
  398.  
  399. bool CreateBlock(int x, int y){
  400.     //Store the combo that was at this location.
  401.     Somaria[SOMARIA_NEWBLOCK_OLDCOMBO] = ComboAt(x,y);
  402.     Somaria[SOMARIA_NEWBLOCK_OLDCOMBO_D] = Screen->ComboD[Somaria[SOMARIA_NEWBLOCK_OLDCOMBO]];
  403.     Somaria[SOMARIA_NEWBLOCK_OLDCOMBO_C] = Screen->ComboC[Somaria[SOMARIA_NEWBLOCK_OLDCOMBO]];
  404.     Somaria[SOMARIA_NEWBLOCK_OLDCOMBO_T] = Screen->ComboT[Somaria[SOMARIA_NEWBLOCK_OLDCOMBO]];
  405.     Somaria[SOMARIA_NEWBLOCK_OLDCOMBO_S] = Screen->ComboS[Somaria[SOMARIA_NEWBLOCK_OLDCOMBO]];
  406.     Somaria[SOMARIA_NEWBLOCK_OLDCOMBO_F] = Screen->ComboF[Somaria[SOMARIA_NEWBLOCK_OLDCOMBO]];
  407.     Somaria[SOMARIA_NEWBLOCK_OLDCOMBO_I] = Screen->ComboI[Somaria[SOMARIA_NEWBLOCK_OLDCOMBO]];
  408.    
  409.    
  410.    
  411.    
  412.     //Chexk that the combo is non-solid.
  413.     if ( Somaria[SOMARIA_NEWBLOCK_OLDCOMBO_S] ) return false;
  414.     else {
  415.         //otherwise, let's make a moving block.
  416.         Screen->ComboD[ Somaria[SOMARIA_NEWBLOCK_OLDCOMBO] ] = CMB_MOVING_COMARIA_D;
  417.         Screen->ComboC[ Somaria[SOMARIA_NEWBLOCK_OLDCOMBO] ] = CMB_MOVING_SOMARIA_C;
  418.         Screen->ComboT[ Somaria[SOMARIA_NEWBLOCK_OLDCOMBO] ] = CMB_MOVING_SOMARIA_T;
  419.         Screen->ComboS[ Somaria[SOMARIA_NEWBLOCK_OLDCOMBO] ] = CMB_MOVING_SOMARIA_S;
  420.         Screen->ComboF[ Somaria[SOMARIA_NEWBLOCK_OLDCOMBO] ] = CMB_MOVING_SOMARIA_F;
  421.         Screen->ComboI[ Somaria[SOMARIA_NEWBLOCK_OLDCOMBO] ] = CMB_MOVING_SOMARIA_I;
  422.         Somaria[SOMARIA_BLOCK_EXISTS] = 1;
  423.        
  424.         //Mark where the Somaria Block is going, and its types.
  425.        
  426.         Somaria[SOMARIA_NEWBLOCK_NEWCOMBO] = SOMARIA_NEWBLOCK_OLDCOMBO;
  427.         Somaria[SOMARIA_NEWBLOCK_NEWCOMBO_D] = Screen->ComboD[Somaria[SOMARIA_NEWBLOCK_OLDCOMBO]];
  428.         Somaria[SOMARIA_NEWBLOCK_NEWCOMBO_C] = Screen->ComboC[Somaria[SOMARIA_NEWBLOCK_OLDCOMBO]];
  429.         Somaria[SOMARIA_NEWBLOCK_NEWCOMBO_T] = Screen->ComboT[Somaria[SOMARIA_NEWBLOCK_OLDCOMBO]];
  430.         Somaria[SOMARIA_NEWBLOCK_NEWCOMBO_S] = Screen->ComboS[Somaria[SOMARIA_NEWBLOCK_OLDCOMBO]];
  431.         Somaria[SOMARIA_NEWBLOCK_NEWCOMBO_F] = Screen->ComboF[Somaria[SOMARIA_NEWBLOCK_OLDCOMBO]];
  432.         Somaria[SOMARIA_NEWBLOCK_NEWCOMBO_I] = Screen->ComboI[Somaria[SOMARIA_NEWBLOCK_OLDCOMBO]];
  433.    
  434.        
  435.         return true;
  436.     }
  437. }
  438.  
  439. //Returns the Nuth combo index of a combo based on a central point, and a direction.
  440. //For example, combo 22 + COMBO_UPRIGHT returns '7',
  441. //as combo 7 is to the upper-right of combo 22.
  442. int AdjacentCombo(int cmb, int dir){
  443.     int combooffsets[13]={-0x10,-0x0F,-0x0E,1,0x10,0x0F,0x0E,-1,-0x10};
  444.     if ( cmb % 16 == 0 ) combooffsets[9] = 1;
  445.     if ( cmb & 15 == 1 ) combooffsets[10] = 1;
  446.     if ( cmb < 0x10 ) combooffsets[11] = 1;
  447.     if ( cmb < 0xAF ) combooffsets[12] = 1;
  448.     if ( combooffsets[9] && ( dir == CMB_LEFT || dir == CMB_UPLEFT || dir == CMB_DOWNLEFT || dir == CMB_LEFTUP ) ) return 0;
  449.     if ( combooffsets[10] && ( dir == CMB_RIGHT || dir == CMB_UPRIGHT || dir == CMB_DOWNRIGHT ) ) return 0;
  450.     if ( combooffsets[11] && ( dir == CMB_UP || dir == CMB_UPRIGHT || dir == CMB_UPLEFT || dir == CMB_DOWNLEFT ) ) return 0;
  451.     if ( combooffsets[12] && ( dir == CMB_DOWN || dir == CMB_DOWNRIGHT || dir == CMB_DOWNLEFT ) ) return 0;
  452.     else if ( cmb > 0 && cmb < 177 ) return cmb + combooffsets[dir];
  453.     else return 0;
  454. }
  455.  
  456. bool CheckMovingBlocksForSomaria(){
  457.     if ( Somaria[SOMARIA_BLOCK_EXISTS] && Screen->MovingBlockX != -1 && Screen->MovingBlockY !+ -1 ) {
  458.         //Compare the XY of any moving block on the screen, and see if it is/was where a somari ablock is located.
  459.        
  460.         if ( ComboAt(Screen->MovingBlockX, Screen->MovingBlockY) == Somaria[SOMARIA_NEWBLOCK_OLDCOMBO] ){
  461.            
  462.             //We found a somaria block thT IS MOVING.
  463.             //Update the combo and location.
  464.             int loc[20];
  465.             loc[0] = AdjacentCombo( Somaria[SOMARIA_NEWBLOCK_OLDCOMBO], Link->Dir );
  466.             loc[1] = ComboAt(Screen->MovingBlockX, Screen->MovingBlockY);
  467.             //Replace the 'old' combo with the stored values, and store the values for the new combo onto
  468.             //which the block moves.
  469.            
  470.             //First, store the values for the old position.
  471.             loc[2] = Somaria[SOMARIA_NEWBLOCK_OLDCOMBO_D];
  472.             loc[3] = Somaria[SOMARIA_NEWBLOCK_OLDCOMBO_T];
  473.             loc[4] = Somaria[SOMARIA_NEWBLOCK_OLDCOMBO_C];
  474.             loc[5] = Somaria[SOMARIA_NEWBLOCK_OLDCOMBO_S];
  475.             loc[6] = Somaria[SOMARIA_NEWBLOCK_OLDCOMBO_F];
  476.             loc[7] = Somaria[SOMARIA_NEWBLOCK_OLDCOMBO_I];
  477.            
  478.             //Then update the combos for the new location, so that we know what *was* under where the block is moving.
  479.             Somaria[SOMARIA_NEWBLOCK_OLDCOMBO_D] = ComboD[ loc[0] ];
  480.             Somaria[SOMARIA_NEWBLOCK_OLDCOMBO_T] = ComboT[ loc[0] ];
  481.             Somaria[SOMARIA_NEWBLOCK_OLDCOMBO_C] = ComboC[ loc[0] ];
  482.             Somaria[SOMARIA_NEWBLOCK_OLDCOMBO_S] = ComboS[ loc[0] ];
  483.             Somaria[SOMARIA_NEWBLOCK_OLDCOMBO_F] = ComboF[ loc[0] ];
  484.             Somaria[SOMARIA_NEWBLOCK_OLDCOMBO_I] = ComboI[ loc[0] ];
  485.            
  486.            
  487.             //then wait a frame, and draw back the old, stored combo values.
  488.            
  489.             Waitframe(); //We may need to wait extra frames between these steps.
  490.            
  491.             ComboD[ loc[1] ] = loc[2];
  492.             ComboT[ loc[1] ] = loc[3];
  493.             ComboC[ loc[1] ] = loc[4];
  494.             ComboS[ loc[1] ] = loc[5];
  495.             ComboF[ loc[1] ] = loc[6];
  496.             ComboI[ loc[1] ] = loc[7];
  497.            
  498.             //Updating should be done.
  499.             return true;
  500.         }
  501.         return false;
  502.        
  503.     }
  504. }
  505.  
  506. bool LiftBlock(int x, int y){
  507.     //Should we change the combo back?
  508.     //Only if we're not in A DUNGEON.
  509.    
  510. }
  511.    
  512. //! Somaria Cane Item
  513. item script CaneOfSomaria{
  514.     void run(){
  515.         if ( !Somaria[SOMARIA_BLOCK_EXISTS] ) {
  516.             if ( Link->Dir == DIR_UP ) CreateBlock( GridX(Link->X), GridY(Link->Y - 16) );
  517.             if ( Link->Dir == DIR_DOWN ) CreateBlock( GridX(Link->X), GridY(Link->Y + 16) );
  518.             if ( Link->Dir == DIR_RIGHT ) CreateBlock( GridX(Link->X + 16), GridY(Link->Y) );
  519.             if ( Link->Dir == DIR_LEFT ) CreateBlock( GridX(Link->X - 16), GridY(Link->Y) );
  520.            
  521.             //! We need to make an lweapon with a Misc. attribute that matches position with the moving block.
  522.                 //! If on a conveyor, we only make the lweapon. The Block combo can be created ONLY when the
  523.                 //! lweapon STOPS MOVING, reaching the end of a conveyor path, and only after a specific number of frames.
  524.                 //! We need these frames for conveyors that change direction, to determine if the block has fully stopped moving.
  525.                 //! Alternatively, we could force the block to move off the conveyor, onto another combo, if it
  526.                 //! is not blocked from further movement, or something.
  527.                 //! Perhaps we could use a 'stop Somaria block' flag?
  528.            
  529.             lweapon block;
  530.            
  531.            
  532.             else {
  533.                 //Change the combo back to what was stored.
  534.                
  535.        
  536.                 Screen->ComboD[Somaria[SOMARIA_NEWBLOCK_OLDCOMBO]] = Somaria[SOMARIA_NEWBLOCK_OLDCOMBO_D];
  537.                 Screen->ComboC[Somaria[SOMARIA_NEWBLOCK_OLDCOMBO]] = Somaria[SOMARIA_NEWBLOCK_OLDCOMBO_C];
  538.                 Screen->ComboT[Somaria[SOMARIA_NEWBLOCK_OLDCOMBO]] = Somaria[SOMARIA_NEWBLOCK_OLDCOMBO_T];
  539.                 Screen->ComboS[Somaria[SOMARIA_NEWBLOCK_OLDCOMBO]] = Somaria[SOMARIA_NEWBLOCK_OLDCOMBO_S];
  540.                 Screen->ComboF[Somaria[SOMARIA_NEWBLOCK_OLDCOMBO]] = Somaria[SOMARIA_NEWBLOCK_OLDCOMBO_F];
  541.                 Screen->ComboI[Somaria[SOMARIA_NEWBLOCK_OLDCOMBO]] = Somaria[SOMARIA_NEWBLOCK_OLDCOMBO_I];
  542.                        
  543.                
  544.                
  545.                 //Create a 4-way beam.
  546.                 lweapon somariabeam[4];
  547.                 Game->PlaySound(SFX_SOMARIA_BEAMS);
  548.                 for ( int q = 0; q < 4; q++ ) {
  549.                     somariabeam[q] = Screen->CreateLWeapon(LW_SOMARIBEAM);
  550.                     somariabeam[q]->X = CenterX(ComboX(Somaria[SOMARIA_NEWBLOCK_OLDCOMBO]));
  551.                     somariabeam[q]->Y = CenterY(ComboY(Somaria[SOMARIA_NEWBLOCK_OLDCOMBO]));
  552.                     somariabeam[q]->UseSprite = SPRITE_SOMARIA_BEAM;
  553.                     if ( GetSomariaBeamPower() ) somariabeam[q]->Damage = SOMARIA_BEAM_POWER;
  554.                     else somariabeam[q]->Damage = SOMARIA_BEAM_POWER;
  555.                     if ( q % 2 != 0 ) somariabeam[q]->UseSprite++;
  556.                 }
  557.                
  558.                 somariabeam[0]->Dir = DIR_UP;
  559.                 somariabeam[1]->Dir = DIR_LEFT;
  560.                 somariabeam[2]->Dir = DIR_DOWN;
  561.                 somariabeam[3]->Dir = DIR_RIGHT;
  562.                
  563.             }
  564.         }
  565.     }
  566. }
  567.                
  568.                
  569. //! Somaria Lift-able Objects
  570.  
  571. //! Somaria Blocks on Conveyors
  572.  
  573. //Move Bombs or Blocks on Conveyors
  574.  
  575. //Global conditions to move all of any object type.
  576. const int CONVEYORS_MOVE_FFCS = 0;
  577. const int CONVEYORS_MOVE_ITEMS = 0; //ZC already does, but you could use this to chane their speed.
  578. const int CONVEYORS_MOVE_LWEAPONS = 0;
  579. const int CONVEYORS_MOVE_EWEAPONS = 0;
  580. const int CONVEYORS_MOVE_NPCS = 0;
  581.  
  582. const int CONVEYORS_MOVE_BOMBS = 1;
  583. const int CONVEYORS_MOVE_WALKING_NPCS = 0;
  584.  
  585. const int CONVEYORS_USE_COLLISION = 1; //Se tto 0 to use coordinates, instead of collision.
  586.  
  587.  bool IsOnConveyor(int cmb){
  588.      return ( ComboT[cmb] == CT_CVLEFT || ComboT[cmb] == CT_CVRIGHT || ComboT[cmb] == CT_CVUP ||ComboT[cmb] == CT_CVDOWN );
  589.  }
  590.  
  591.  const int WEAP_CONVEY_TIMER = 1; //Misc Index
  592.  
  593.  const int CONVEY_TIME = 20; //How many frames to wait before moving one pixel on a conveyor, +1.
  594.                 //! The movement occurs at '1', not '0'.
  595.  
  596.  void MarkObjectConveyor(lweapon l) { if ( !l->Misc[WEAP_CONVEY_TIMER] ) l->Misc[WEAP_CONVEY_TIMER] = CONVEY_TIME; }
  597.  
  598.  void MoveObjectConveyor(lweapon l) {
  599.     if ( l->Misc[WEAP_CONVEY_TIMER] == 1 ) {
  600.         //Move it
  601.         if ( ComboT[ComboAt(l->X, l->Y)] == CT_CVLEFT ) l->X--;
  602.         if ( ComboT[ComboAt(l->X, l->Y)] == CT_CVRIGHT ) l->X++;
  603.         if ( ComboT[ComboAt(l->X, l->Y)] == CT_CVUP ) l->Y--;
  604.         if ( ComboT[ComboAt(l->X, l->Y)] == CT_CVDOWN ) l->Y++;
  605.     }
  606.     if ( l->Misc[WEAP_CONVEY_TIMER] > 1 ) l->Misc[WEAP_CONVEY_TIMER]--;
  607.     if ( !l->Misc[WEAP_CONVEY_TIMER] && IsOnConveyor(l) ) MarkObjectConveyor(l);
  608. }
  609.  
  610.  
  611.  void MarkObjectConveyor(eweapon l) { if ( !l->Misc[WEAP_CONVEY_TIMER] ) l->Misc[WEAP_CONVEY_TIMER] = CONVEY_TIME; }
  612.  
  613.  void MoveObjectConveyor(eweapon l) {
  614.     if ( l->Misc[WEAP_CONVEY_TIMER] == 1 ) {
  615.         //Move it
  616.         if ( ComboT[ComboAt(l->X, l->Y)] == CT_CVLEFT ) l->X--;
  617.         if ( ComboT[ComboAt(l->X, l->Y)] == CT_CVRIGHT ) l->X++;
  618.         if ( ComboT[ComboAt(l->X, l->Y)] == CT_CVUP ) l->Y--;
  619.         if ( ComboT[ComboAt(l->X, l->Y)] == CT_CVDOWN ) l->Y++;
  620.     }
  621.     if ( l->Misc[WEAP_CONVEY_TIMER] > 1 ) l->Misc[WEAP_CONVEY_TIMER]--;
  622.     if ( !l->Misc[WEAP_CONVEY_TIMER] && IsOnConveyor(l) ) MarkObjectConveyor(l);
  623. }
  624.  
  625.  void MarkObjectConveyor(item l) { if ( !l->Misc[WEAP_CONVEY_TIMER] ) l->Misc[WEAP_CONVEY_TIMER] = CONVEY_TIME; }
  626.  
  627.  void MoveObjectConveyor(item l) {
  628.     if ( l->Misc[WEAP_CONVEY_TIMER] == 1 ) {
  629.         //Move it
  630.         if ( ComboT[ComboAt(l->X, l->Y)] == CT_CVLEFT ) l->X--;
  631.         if ( ComboT[ComboAt(l->X, l->Y)] == CT_CVRIGHT ) l->X++;
  632.         if ( ComboT[ComboAt(l->X, l->Y)] == CT_CVUP ) l->Y--;
  633.         if ( ComboT[ComboAt(l->X, l->Y)] == CT_CVDOWN ) l->Y++;
  634.     }
  635.     if ( l->Misc[WEAP_CONVEY_TIMER] > 1 ) l->Misc[WEAP_CONVEY_TIMER]--;
  636.     if ( !l->Misc[WEAP_CONVEY_TIMER] && IsOnConveyor(l) ) MarkObjectConveyor(l);
  637. }
  638.  
  639.  void MarkObjectConveyor(ffc l) { if ( !l->Misc[WEAP_CONVEY_TIMER] ) l->Misc[WEAP_CONVEY_TIMER] = CONVEY_TIME; }
  640.  
  641.  void MoveObjectConveyor(ffc l) {
  642.     if ( l->Misc[WEAP_CONVEY_TIMER] == 1 ) {
  643.         //Move it
  644.         if ( ComboT[ComboAt(l->X, l->Y)] == CT_CVLEFT ) l->X--;
  645.         if ( ComboT[ComboAt(l->X, l->Y)] == CT_CVRIGHT ) l->X++;
  646.         if ( ComboT[ComboAt(l->X, l->Y)] == CT_CVUP ) l->Y--;
  647.         if ( ComboT[ComboAt(l->X, l->Y)] == CT_CVDOWN ) l->Y++;
  648.     }
  649.     if ( l->Misc[WEAP_CONVEY_TIMER] > 1 ) l->Misc[WEAP_CONVEY_TIMER]--;
  650.     if ( !l->Misc[WEAP_CONVEY_TIMER] && IsOnConveyor(l) ) MarkObjectConveyor(l);
  651. }
  652.  
  653.  
  654.  void MoveObjectConveyorCollision(ffc l, int cmb) {
  655.     if ( l->Misc[WEAP_CONVEY_TIMER] == 1 ) {
  656.         //Move it
  657.         if ( Collision(l,cmb) && ComboT[cmb] == CT_CVLEFT ) l->X--;
  658.         if ( Collision(l,cmb) && ComboT[cmb] == CT_CVRIGHT ) l->X++;
  659.         if ( Collision(l,cmb) && ComboT[cmb] == CT_CVUP ) l->Y--;
  660.         if ( Collision(l,cmb) && ComboT[cmb] == CT_CVDOWN ) l->Y++;
  661.     }
  662.     if ( l->Misc[WEAP_CONVEY_TIMER] > 1 ) l->Misc[WEAP_CONVEY_TIMER]--;
  663.     if ( !l->Misc[WEAP_CONVEY_TIMER] && IsOnConveyor(l) ) MarkObjectConveyor(l);
  664. }
  665.  
  666.  void MoveObjectConveyorCollision(item l, int cmb) {
  667.     if ( l->Misc[WEAP_CONVEY_TIMER] == 1 ) {
  668.         //Move it
  669.         if ( Collision(l,cmb) && ComboT[cmb] == CT_CVLEFT ) l->X--;
  670.         if ( Collision(l,cmb) && ComboT[cmb] == CT_CVRIGHT ) l->X++;
  671.         if ( Collision(l,cmb) && ComboT[cmb] == CT_CVUP ) l->Y--;
  672.         if ( Collision(l,cmb) && ComboT[cmb] == CT_CVDOWN ) l->Y++;
  673.     }
  674.     if ( l->Misc[WEAP_CONVEY_TIMER] > 1 ) l->Misc[WEAP_CONVEY_TIMER]--;
  675.     if ( !l->Misc[WEAP_CONVEY_TIMER] && IsOnConveyor(l) ) MarkObjectConveyor(l);
  676. }
  677.  
  678.  void MoveObjectConveyorCollision(lweapon l, int cmb) {
  679.     if ( l->Misc[WEAP_CONVEY_TIMER] == 1 ) {
  680.         //Move it
  681.         if ( Collision(l,cmb) && ComboT[cmb] == CT_CVLEFT ) l->X--;
  682.         if ( Collision(l,cmb) && ComboT[cmb] == CT_CVRIGHT ) l->X++;
  683.         if ( Collision(l,cmb) && ComboT[cmb] == CT_CVUP ) l->Y--;
  684.         if ( Collision(l,cmb) && ComboT[cmb] == CT_CVDOWN ) l->Y++;
  685.     }
  686.     if ( l->Misc[WEAP_CONVEY_TIMER] > 1 ) l->Misc[WEAP_CONVEY_TIMER]--;
  687.     if ( !l->Misc[WEAP_CONVEY_TIMER] && IsOnConveyor(l) ) MarkObjectConveyor(l);
  688. }
  689.  
  690.  void MoveObjectConveyorCollision(eweapon l, int cmb) {
  691.     if ( l->Misc[WEAP_CONVEY_TIMER] == 1 ) {
  692.         //Move it
  693.         if ( Collision(l,cmb) && ComboT[cmb] == CT_CVLEFT ) l->X--;
  694.         if ( Collision(l,cmb) && ComboT[cmb] == CT_CVRIGHT ) l->X++;
  695.         if ( Collision(l,cmb) && ComboT[cmb] == CT_CVUP ) l->Y--;
  696.         if ( Collision(l,cmb) && ComboT[cmb] == CT_CVDOWN ) l->Y++;
  697.     }
  698.     if ( l->Misc[WEAP_CONVEY_TIMER] > 1 ) l->Misc[WEAP_CONVEY_TIMER]--;
  699.     if ( !l->Misc[WEAP_CONVEY_TIMER] && IsOnConveyor(l) ) MarkObjectConveyor(l);
  700. }
  701.  
  702.  void MoveObjectConveyorCollision(npc l, int cmb) {
  703.     if ( l->Misc[WEAP_CONVEY_TIMER] == 1 ) {
  704.         //Move it
  705.         if ( Collision(l,cmb) && ComboT[cmb] == CT_CVLEFT ) l->X--;
  706.         if ( Collision(l,cmb) && ComboT[cmb] == CT_CVRIGHT ) l->X++;
  707.         if ( Collision(l,cmb) && ComboT[cmb] == CT_CVUP ) l->Y--;
  708.         if ( Collision(l,cmb) && ComboT[cmb] == CT_CVDOWN ) l->Y++;
  709.     }
  710.     if ( l->Misc[WEAP_CONVEY_TIMER] > 1 ) l->Misc[WEAP_CONVEY_TIMER]--;
  711.     if ( !l->Misc[WEAP_CONVEY_TIMER] && IsOnConveyor(l) ) MarkObjectConveyor(l);
  712. }
  713.  
  714. void ConveyorObjects(){
  715.     lweapon l; item i; eweapon e; npc n; ffc f; int q;
  716.     if ( CONVEYORS_MOVE_BOMBS ) {
  717.         for ( q = Screen->NumLWeapons(); q > 0; q-- ) {
  718.             l = Screen->LoadLWeapon(q);
  719.             if ( l->ID == LW_BOMB || l->ID == LW_SBOMB ) MoveObjectConveyor(l);
  720.         }
  721.     }
  722.     //Add more definitions.
  723.     //Somaria Blocks
  724.    
  725.     //Walking NPCs? -- How should we handle ghosted NPCs?
  726. }
  727.  
  728. void ConveyorObjectsCollision(){
  729.     lweapon l; item i; eweapon e; npc n; ffc f; int q; int cmb;
  730.     if ( CONVEYORS_MOVE_BOMBS ) {
  731.         for ( cmb = 0; cmb < 176; cmb++ ) {
  732.             for ( q = Screen->NumLWeapons(); q > 0; q-- ) {
  733.                 l = Screen->LoadLWeapon(q);
  734.                 if ( l->ID == LW_BOMB || l->ID == LW_SBOMB ) MoveObjectConveyorCollision(l,cmb);
  735.             }
  736.         }
  737.     }
  738.     //Add more definitions.
  739.     //Somaria Blocks
  740.    
  741.     //Walking NPCs? -- How should we handle ghosted NPCs?
  742. }
  743.  
  744. global script conveyor_test{
  745.     void run(){
  746.         while(true){
  747.             if ( !CONVEYORS_USE_COLLISION ) ConveyorObjects();
  748.             if ( CONVEYORS_USE_COLLISION ) ConveyorObjectsCollision();
  749.             Waitdraw();
  750.             Waitframe();
  751.         }
  752.     }
  753. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement