Jump to content

Photo

Need a modification of the Mine Cart Script


  • Please log in to reply
8 replies to this topic

#1 Rastael

Rastael

    Wizard

  • Members
  • Real Name:Raphael
  • Location:Austria

Posted 31 July 2013 - 10:20 AM

Heyho :)

 

I need help with the mine cart script. It works great, but it's a bit useless.

So I need a small modification:

When the mine cart (ffc) touches a specific combotype (script 4), the combo should change to the next combo on the list (so a closed door should open, when the minecart touches it). When the minecart doesn't touches the combo anymore, it should be the orginal combo again (the door should close again).

That's the way, the mine carts work in the oracle games.

Can anybody do this for me please? ^^

global script Slot_2{
 void run(){

  link_on_cart = false;  

  while(true){

   Waitframe();
  }
 }
}

global script Slot_3{
 void run(){

  link_on_cart = false;
 }
}









bool link_on_cart;
const int SFX_SWITCH = 7;
const int CartSFXLength = 30;
const int SFX_CART           = 72;

const int CF_DOWNRIGHT           = 43;
const int CF_DOWNLEFT	         = 44; 
const int CF_UPRIGHT             = 45; 
const int CF_UPLEFT              = 46;     

const int CT_RAIL    = 144; // SCRIPT3

// Mine Cart script
// How to set it:
// - give all the rail combos the CT_RAIL combo type
// - set the right flags to the turning rail combos (see the following CF_...)
// - place an ffc with the combo of the mine cart at the beginning of the rail
// - either set the combo following the cart one a combo to be drawn above Link when on the cart, or set the LTM
// - place another mine cart ffc in each other place you want it to be able to start again
// - either include some solidifyFFC function or comment the corresponding line below (under RailSwitch)

// Inputs:
// D0: initial direction of the cart
// D1: speed of the cart (leave 0 to have it the default "1")

ffc script MineCart{

void run(int dir,int speed){
  int CartMoving = 0;

  if(speed==0) speed = 1;

  if(link_on_cart){
   this->Data = 0;
   Quit();
  }

  // Main loop
  while(true){
   
   this->X = GridX(this->X+8);
   this->Y = GridY(this->Y+8);

   link_on_cart = false;
   CartMoving = 0;
   this->Flags[FFCF_CARRYOVER] = false;

   while(Distance(this->X,this->Y,Link->X,Link->Y)>8) Waitframe();
   
   Link->Jump = 1;
   Game->PlaySound(45);
   Waitframe();
   int link_dir = Link->Dir;
   while(Link->Z > 0){
    if(CanWalk(Link->X,Link->Y,link_dir,1,false)){
     Link->X += MoveX(link_dir);
     Link->Y += MoveY(link_dir);
    }
    WaitNoAction();
   }
   Link->X = this->X;
   Link->Y = this->Y;

   this->Flags[FFCF_PRELOAD] = false;
   //this->Flags[FFCF_PRELOAD] = true;

   int previous_link_x = Link->X;
   int previous_link_y = Link->Y;

   int going_out = 0;
   int data = this->Data;

   // Move loop
   while(true){

    this->Data = data;

    link_on_cart = true;
    this->Flags[FFCF_CARRYOVER] = true;
    if(CartMoving%CartSFXLength==0){
      Game->PlaySound(SFX_CART);
    }
    CartMoving++;

    // setting new position
    int x_new = Link->X + speed*MoveX(dir);
    int y_new = Link->Y + speed*MoveY(dir);

    if((dir==DIR_UP && isOutOfScreen(x_new+8,y_new-8,1,1)) || 
       (dir==DIR_DOWN && isOutOfScreen(x_new+8,y_new,1,1)) || 
       (dir==DIR_LEFT && isOutOfScreen(x_new,y_new+12,1,1)) || 
       (dir==DIR_RIGHT && isOutOfScreen(x_new+16,y_new+12,1,1))
    )
     going_out = 2;
    else if(going_out>0)
     going_out --;
    if(going_out>0){
     if(dir==DIR_UP) y_new = Link->Y + 11*16;
     if(dir==DIR_DOWN) y_new = Link->Y - 11*16;
     if(dir==DIR_LEFT) x_new = Link->X + 16*16;
     if(dir==DIR_RIGHT) x_new = Link->X - 16*16;
     //if(this->Data != INV_COMBO_ID){
     // data = this->Data;
     // this->Data = INV_COMBO_ID;
     //}
    }
    //if(going_out>0) Link->HP = 0;
    //if(going_out==0) this->Data = data;
    
    // changing dir
    int loc0 = ComboAt(CenterLinkX(),CenterLinkY());
    bool changing_dir = false;
    if(Abs(ComboX(loc0)-Link->X)<speed && Abs(ComboY(loc0)-Link->Y)<speed){
     changing_dir = true;
     if(Screen->ComboI[loc0]==CF_DOWNRIGHT || Screen->ComboF[loc0]==CF_DOWNRIGHT){
      if(dir == DIR_UP) dir = DIR_RIGHT;
      else if(dir == DIR_LEFT) dir = DIR_DOWN;
     }
     else if(Screen->ComboI[loc0]==CF_DOWNLEFT || Screen->ComboF[loc0]==CF_DOWNLEFT){
      if(dir == DIR_RIGHT) dir = DIR_DOWN;
      else if(dir == DIR_UP) dir = DIR_LEFT;
     }
     else if(Screen->ComboI[loc0]==CF_UPLEFT || Screen->ComboF[loc0]==CF_UPLEFT){
      if(dir == DIR_RIGHT) dir = DIR_UP;
      else if(dir == DIR_DOWN) dir = DIR_LEFT;
     }
     else if(Screen->ComboI[loc0]==CF_UPRIGHT || Screen->ComboF[loc0]==CF_UPRIGHT){
      if(dir == DIR_DOWN) dir = DIR_RIGHT;
      else if(dir == DIR_LEFT) dir = DIR_UP;
     }
     else changing_dir = false;
    }
    
    if(going_out==0)
     if(Screen->ComboT[ComboAt(Link->X+AtFrontX(dir),Link->Y+AtFrontY(dir))] != CT_RAIL 
       && !isOutOfScreen(Link->X+AtFrontX(dir),Link->Y+AtFrontY(dir),1,1)) break;
        
    Link->X += speed*MoveX(dir);
    Link->Y += speed*MoveY(dir);
    this->X = Link->X;
    this->Y = Link->Y;
    //if(this->Data == INV_COMBO_ID) this->Data = data;
    
    // try to fix...
    if(Link->Action == LA_SCROLLING || going_out>0){
     this->X = x_new;
     this->Y = y_new;
    }

    if(dir==DIR_UP || dir==DIR_DOWN) Link->X = GridX(Link->X);
    if(dir==DIR_LEFT || dir==DIR_RIGHT) Link->Y = GridX(Link->Y);

    if(Link->InputUp) Link->Dir = DIR_UP;
    if(Link->InputDown) Link->Dir = DIR_DOWN;
    if(Link->InputLeft) Link->Dir = DIR_LEFT;
    if(Link->InputRight) Link->Dir = DIR_RIGHT;
    NoMoveAction();

    if(Link->Action == LA_GOTHURTLAND){
     Link->X = previous_link_x;
     Link->Y = previous_link_y;
    }
    previous_link_x = Link->X;
    previous_link_y = Link->Y;

    // temp
    Screen->DrawInteger(3, 16, 16, FONT_Z1, 1, -1, 0,0, Link->X, 0, 128);

    Link->DrawYOffset = -4;
    // try to fix...
    //if(Link->Action != LA_SCROLLING)
     Screen->FastCombo(3,this->X,this->Y,this->Data+1,this->CSet,128); // comment this out if using LTM
    Waitframe();
   }
   // end of Move loop

   Link->DrawYOffset = 0;
   link_on_cart = false;
   CartMoving = 0;
   Link->Jump = 1;
   Game->PlaySound(45);
   for(int t=0;t<20;t++){
     Link->X += MoveX(dir);
     Link->Y += MoveY(dir);
     WaitNoAction(); 
   }
   dir = OppositeDir(dir);
   
   // example of LTM implementation (never tested)
   // if(Link->Item[I_CART]) Link->Item[I_CART] = false; // you might have to add this somewhere else as well in the global script..
   
   Waitframe();
  }
 }
}














// Inputs:
//  D0: default position: 0=left, 1=right
//  D1: location of the rail combo to switch
//  D2: combo to set when the switch is on left position
//  D3: combo to set when the switch is on right position
// 
// Notes:
//  Screen->D[3] keeps memory of the position: 0=left, 1=right


ffc script RailSwitch{
void run(int def,int cmb_loc,int left_cmb,int right_cmb){
  int time = 0;
  lweapon w;
  
  // set the combos
  if(Screen->D[3]==0) Screen->ComboD[cmb_loc] = left_cmb;
  else Screen->ComboD[cmb_loc] = right_cmb;
  
  if(Screen->D[3]==1 && def==0) this->Data += 1;
  else if(Screen->D[3]==0 && def==1) this->Data -= 1;
  
  while(true){
   GB_SolidifyFFC(this); // external function to make the switch FFC solid, in alternative just comment out and put an invisible solid combo just under the ffc
   
   // change
   if(time < 30) time ++;
   else{
    for(int i=1;i<=Screen->NumLWeapons();i++){
     w = Screen->LoadLWeapon(i);
     if(Collision(this,w) && w->Damage >0 && w->ID != LW_BOMB){
      Game->PlaySound(SFX_SWITCH);
      for(int t=0;t<10;t++) WaitNoAction();
      if(Screen->D[3]==0){
       Screen->D[3] = 1;
       this->Data += 1;
       Screen->ComboD[cmb_loc] = right_cmb;
      }
      else{
       Screen->D[3] = 0;
       this->Data -= 1;
       Screen->ComboD[cmb_loc] = left_cmb;
      }
      time = 0;
      break;
     }
    }
   }
   Waitframe();
  }
}
}

int MoveX(int dir){
if(dir == DIR_LEFT || dir == DIR_LEFTUP || dir == DIR_LEFTDOWN) return -1;
if(dir == DIR_RIGHT || dir == DIR_RIGHTUP || dir == DIR_RIGHTDOWN) return 1;
return 0;
}

int MoveY(int dir){
if(dir == DIR_UP || dir == DIR_LEFTUP || dir == DIR_RIGHTUP) return -1;
if(dir == DIR_DOWN || dir == DIR_LEFTDOWN || dir == DIR_RIGHTDOWN) return 1;
return 0;
}


Edited by Lord Settra!, 31 July 2013 - 10:26 AM.


#2 Avaro

Avaro

    >w<

  • Members

Posted 31 July 2013 - 12:00 PM

I think you just have to add this to your script, but I'm not sure as I haven't looked over it.

int changedCombo = 0; //this goes before the while (true)
if ( changedCombo == 0 && Screen->ComboT[ComboAt(this->X+8, this->Y+8)] == CT_SCRIPT4 ){ //if combo under this ffc is script 4 type
    changedCombo = ComboAt(this->X+8, this->Y+8); //store its position on the screen
    Screen->ComboD[changedCombo] ++; //and change it to the next in the list
}
if ( changedCombo != 0 && changedCombo != ComboAt(this->X+8, this->Y+8){ //if the stored combo is not under this ffc
    Screen->ComboD[changedCombo] --; //change it back
    changedCombo = 0; //and unstore(?) it
}

Should work

:D


Edited by Avataro, 31 July 2013 - 12:01 PM.


#3 Rastael

Rastael

    Wizard

  • Members
  • Real Name:Raphael
  • Location:Austria

Posted 31 July 2013 - 04:22 PM

Hey Avataro, I didn't know that you're a scripter now. ^^

 

I made a mistake, so it doesn't work. The part with the comnbotype was nonesense, because the minecart needs script3-combotype to work. Can you change the part with script4-combotype to a specific comboflag?

 

Vielen Dank für deine Hilfe. :D



#4 Avaro

Avaro

    >w<

  • Members

Posted 31 July 2013 - 07:32 PM

Kein Problem! And yes, I learned it because I think that scripting makes ZC a lot easier and allows for cool things. I am glad that it is not too hard to understand :D

Still don't know a lot of it though.

 

If you need to use flags instead of combotype thats no problem too. Just change that line that checks for the combo type into this new line that checks for a flag now:

if ( changedCombo == 0 && ComboFI(ComboAt(this->X+8, this->Y+8), CF_SCRIPT4) == true ){ //if combo under this ffc is script 4 flag

I know this from the std_functions.zh file from the zc folder btw.



#5 Rastael

Rastael

    Wizard

  • Members
  • Real Name:Raphael
  • Location:Austria

Posted 01 August 2013 - 07:10 AM

Strange, it doesn't work...

 

I put this before the "waitframe();"

// change Flag 42 combos

if ( changedCombo == 0 && ComboFI(ComboAt(this->X+8, this->Y+8), CF_ENEMY5) == true ){ //if combo under this ffc is script 4 flag
    changedCombo = ComboAt(this->X+8, this->Y+8); //store its position on the screen
    Screen->ComboD[changedCombo] ++; //and change it to the next in the list
}
if ( changedCombo != 0 && changedCombo != ComboAt(this->X+8, this->Y+8)){ //if the stored combo is not under this ffc
    Screen->ComboD[changedCombo] --; //change it back
    changedCombo = 0; //and unstore(?) it
}

Do you have an idea, why it doesn't work?


Edited by Lord Settra!, 01 August 2013 - 07:11 AM.


#6 Avaro

Avaro

    >w<

  • Members

Posted 01 August 2013 - 08:16 AM

Ok I have a better idea then ;).

Just add this new script for the minecart doors in every room where you use those doors:

ffc script MinecartDoorsScript{
    void run(){
        int changedCombo = 0;
        ffc->Flags[FFCF_ETHEREAL] = true;
        while(true){           
            if ( changedCombo == 0 && ComboFI(ComboAt(Link->X+8, Link->Y+8), CF_ENEMY5) == true ){ //if combo under link is enemy 5 flag
                changedCombo = ComboAt(Link->X+8, Link->Y+8); //store its position on the screen
                Screen->ComboD[changedCombo] ++; //and change it to the next in the list
            }
            if ( changedCombo != 0 && changedCombo != ComboAt(Link->X+8, Link->Y+8)){ //if the stored combo is not under link
                Screen->ComboD[changedCombo] --; //change it back
                changedCombo = 0; //and unstore(?) it
            }
            Waitframe();
        }
    }
}

I hope you don't mind adding a new script to the rooms instead of editing the minecart script itself, but this should definetly work. Just give this script any blank combo, except combo 0 of course, and simply leave it in the top left corner of the screen, as it's postition where you place it doesn't matter.

 

Make sure that the door combos have the enemy 5 combo flag and are unwalkable! You should also add a sound effect for opening and closing by the way :D

Good luck and let me know if it works.



#7 Rastael

Rastael

    Wizard

  • Members
  • Real Name:Raphael
  • Location:Austria

Posted 03 August 2013 - 04:46 AM

Thx again for helping me. :)

 

But I can't compile the script... :(

 

b855ba2fb12e898503191a1e72320cd7.jpg

 

 

 

 

 

 

 

It's because of this line:

        ffc->Flags[FFCF_ETHEREAL] = true;

I think, there's somthing wrong with the "ffc->Flags"?

 



#8 Avaro

Avaro

    >w<

  • Members

Posted 03 August 2013 - 05:35 AM

Hm, I don't know whats wrong with that. I've never used the ffc flags function yet. I think you can just remove the line then, it is not so important to have the ffc ethereal.

So, yes, the line is not needed ;)

 

EDIT: Oops. Maybe you have to change ffc->Flags to this->Flags :D


Edited by Avataro, 03 August 2013 - 06:59 AM.


#9 Rastael

Rastael

    Wizard

  • Members
  • Real Name:Raphael
  • Location:Austria

Posted 03 August 2013 - 08:09 AM

Yeeeees, it works, thank you so much! ^^

 

Just another thing: I tried to add two soundeffects, when the flag42-combo disappears and appears. But the sfx doesn't play...

Can you tell me, where I have to put that line? I think, I understand your script, but I don't know, why the soundeffects are not working.

 

I tried it this way:

ffc script MinecartDoorsScript{
    void run(){
        int changedCombo = 0;
        ffc->Flags[FFCF_ETHEREAL] = true;
        while(true){           
            if ( changedCombo == 0 && ComboFI(ComboAt(Link->X+8, Link->Y+8), CF_ENEMY5) == true ){ //if combo under link is enemy 5 flag
                changedCombo = ComboAt(Link->X+8, Link->Y+8); //store its position on the screen
                Game->PlaySound(9);
                Screen->ComboD[changedCombo] ++; //and change it to the next in the list
            }
            if ( changedCombo != 0 && changedCombo != ComboAt(Link->X+8, Link->Y+8)){ //if the stored combo is not under link
                Screen->ComboD[changedCombo] --; //change it back
                Game->PlaySound(99);
                changedCombo = 0; //and unstore(?) it
            }
            Waitframe();
        }
    }
}

Edit:

Sry, it was my fault. I forgot to compile the script again after updating. The soundeffects are working. XD


Edited by Lord Settra!, 03 August 2013 - 08:13 AM.



1 user(s) are reading this topic

0 members, 1 guests, 0 anonymous users