SOLVED: Help me check my functions not firing random int events properly

Started by Slasher, Mon 25/07/2016 17:34:07

Previous topic - Next topic

Slasher

Hi,

ags 3.4.0

Sometimes it seems that some functions don't run the variable events though mostly they do which i find odd.

The variable 'Weight' does not always get updated on the LWeight label. Everything else seems to work OK.

For anyone who has the time to check over my code and check for any loopholes and can advice that would be great.

I hope you can understand. I will try to elaborate a bit more.

Fish collides with Rod, if conditions approve then Cod_Bass_Skate() runs and assigns a graphic to objectX. This graphic will determine the type of fish and also what weight which is determine by the int selection of the fish,. Example: Cod_Weight()
and so forth...This Weight gets added to the LWeight label.

Thank you.

Scripts

Room Functions:
Spoiler

Code: ags


// room script file

function Cod_Bass_Skate()
{
 int ran=Random(3);
     
 if (ran == 0) {
 object[3].Graphic=84;      
 }
 else if (ran == 1) {
 object[3].Graphic=93;    
 }
 else if (ran == 2) {
 object[3].Graphic=83; 
 }
}
 
 function Cod_Weight()
{
  int CodWeight=Random(3);

  if (CodWeight == 0) 
  {
  Weight=(Weight +21);
  }
  else if (CodWeight == 1) 
  {
  Weight=(Weight +23);
  }
  else if (CodWeight == 2) 
  {
  Weight=(Weight +27);
  }
}

function Bass_Weight()
{
  int BassWeight=Random(3);

  if (BassWeight == 0) 
  {
  Weight=(Weight +7);
  }
  else if (BassWeight == 1) 
  {
  Weight=(Weight +9);
}
  else if (BassWeight == 2)
  {
  Weight=(Weight +11);
  }
}


 function Skate_Weight()
{
  int SkateWeight=Random(3);

  if (SkateWeight == 0)
  {
  Weight=(Weight +18);
  }
  else if (SkateWeight == 1) 
  {
  Weight=(Weight +23);
  }
  else if (SkateWeight == 2) 
  {
  Weight=(Weight +27);
  }
}

[close]
Room Rep Exec
Spoiler

Code: ags

function room_RepExec()
{
 if(PPColliding.CWithC(cFish1, cRod) && Hooks==3 && Depths==3 && gCatch.Visible==false && gSetup.Visible==false && (Baits==1 || Baits==2 || Baits==4))
 {
 
 Cod_Bass_Skate(); // Runs Random ints to determine graphic[n]
 cRod.LockView(9);
 cRod.Animate(2,4, eRepeat, eNoBlock, eBackwards);
 cLuke.Say("Look at my rod bending! It must be something big!");
 cRod.LockView(11);
 cRod.Animate(2,4, eRepeat, eNoBlock, eBackwards);
 aREELING.Play();
 cRod.LockView(4);
 cRod.Animate(4,4, eRepeat, eNoBlock, eBackwards);
 cFish1.Move(cFish1.x+190, cFish1.y, eBlock, eWalkableAreas);
 Wait(90);
 oobjectx.Move(oobjectx.X, oobjectx.Y-90, 1, eBlock, eAnywhere);
 oobjectx.Move(oobjectx.X, oobjectx.Y-40,  1, eBlock, eAnywhere);
 cRod.LockView(9);
 cRod.Animate(2,4, eRepeat, eNoBlock, eBackwards);
 aREELING.Stop();
 
 if(object[3].Graphic==84)  // Random int selected in Cod_Bass_Skate()
 {
 cLuke.Say("I've caught a massive Cod!");
 Cod_caught=(Cod_caught +1);
 Cod_Weight();
 cRod.UnlockView();
 oobjectx.Transparency=100;
 oobjectx.Move(oobjectx.X, oobjectx.Y+130,  9, eBlock, eAnywhere);
 oobjectx.Transparency=0;
 aREELING.Play();
 Wait(90);
 aREELING.Stop();
 cLuke.Say("I hope I catch more of those.");
 Wait(1);
 LWeight.Text=String.Format("%d",Weight);

}
 
 else if(object[3].Graphic==93)  // Random int selected in Cod_Bass_Skate()
 {  
 cLuke.Say("I've caught a big Bass!");
 Bass_Weight();
 Bass_caught=(Bass_caught +1);
 cRod.UnlockView();
 oobjectx.Transparency=100;
 oobjectx.Move(oobjectx.X, oobjectx.Y+130,  9, eBlock, eAnywhere);
 oobjectx.Transparency=0;
 aREELING.Play();
 Wait(90);
 aREELING.Stop();
 cLuke.Say("I hope I catch more of those.");
 Wait(1);
 LWeight.Text=String.Format("%d",Weight);

} 
 else if(object[3].Graphic==83) // Random int selected in Cod_Bass_Skate()
 {
 cLuke.Say("I've caught a massive Thornback!");
 Skate_caught=(Skate_caught +1);
 Skate_Weight();
 cRod.UnlockView();
 oobjectx.Transparency=100;
 oobjectx.Move(oobjectx.X, oobjectx.Y+130,  9, eBlock, eAnywhere);
 oobjectx.Transparency=0;
 aREELING.Play();
 Wait(90);
 aREELING.Stop();
 cLuke.Say("I hope I catch more of those.");
 Wait(1);
 LWeight.Text=String.Format("%d",Weight);
 }
 }
 }

[close]
Global Rep Exec Always
Spoiler

Code: ags

 function repeatedly_execute_always() {
  
 LCod.Text=String.Format("%d",Cod_caught);
 LBass.Text=String.Format("%d",Bass_caught);
 LSkate.Text=String.Format("%d",Skate_caught);
 LWeight.Text=String.Format("%d",Weight);
}

[close]

Well, of course i will carry on trying but if you can help that would be great.


slasher ;)





Crimson Wizard

Indentation though! Oh well, maybe it is not the worst of I've seen :P.

Slasher, before even looking into your problem, I have couple of advices to you, hope you won't mind, because they may improve your code and make bug searching easier:

1. When you are writing ROOM script, there is usually no need to address objects by their numeric index, like object[3]. In the room script you can access objects with their script names you have on property panel, for example if your object #3 is called "oMyObject":
Spoiler

Code: ags

function Cod_Bass_Skate()
{
  int ran=Random(3);    
  if (ran == 0) {
    oMyObject.Graphic=84;      
  }
  else if (ran == 1) {
    oMyObject.Graphic=93;    
  }
  else if (ran == 2) {
    oMyObject.Graphic=83; 
  }
}

[close]

2. In AGS script you do not have to write A = A + 1, instead you can do A += 1 for less code:
Spoiler

Code: ags

function Cod_Weight()
{
  int CodWeight=Random(3);
 
  if (CodWeight == 0) 
  {
    Weight += 21;
  }
  else if (CodWeight == 1) 
  {
    Weight += 23;
  }
  else if (CodWeight == 2) 
  {
    Weight += 27;
  }
}

[close]


3. But the most important advice I have is to separate events in code as much as possible (or rather as much as sane) so that every function was dealing with very limited issue.
For example, you Room's RepExec script is pretty long and deals with several different possible cases. If you will have more fish types, or more possible events, the amount of code there will increase, increasing function complexity and decreasing clarity.
This is why I would suggest putting each case into separate function and call them from RepExec instead of keeping all the code in there. For example:

Spoiler

Code: ags

function WhenGotCod()
{
  cLuke.Say("I've caught a massive Cod!");
  Cod_caught=(Cod_caught +1);
  Cod_Weight();
  cRod.UnlockView();
  oobjectx.Transparency=100;
  oobjectx.Move(oobjectx.X, oobjectx.Y+130,  9, eBlock, eAnywhere);
  oobjectx.Transparency=0;
  aREELING.Play();
  Wait(90);
  aREELING.Stop();
  cLuke.Say("I hope I catch more of those.");
  Wait(1);
  LWeight.Text=String.Format("%d",Weight);
}

function WhenGotBass()
{
  cLuke.Say("I've caught a big Bass!");
  Bass_Weight();
  Bass_caught=(Bass_caught +1);
  cRod.UnlockView();
  oobjectx.Transparency=100;
  oobjectx.Move(oobjectx.X, oobjectx.Y+130,  9, eBlock, eAnywhere);
  oobjectx.Transparency=0;
  aREELING.Play();
  Wait(90);
  aREELING.Stop();
  cLuke.Say("I hope I catch more of those.");
  Wait(1);
  LWeight.Text=String.Format("%d",Weight);
}

function WhenGotThornback()
{
  cLuke.Say("I've caught a massive Thornback!");
  Skate_caught=(Skate_caught +1);
  Skate_Weight();
  cRod.UnlockView();
  oobjectx.Transparency=100;
  oobjectx.Move(oobjectx.X, oobjectx.Y+130,  9, eBlock, eAnywhere);
  oobjectx.Transparency=0;
  aREELING.Play();
  Wait(90);
  aREELING.Stop();
  cLuke.Say("I hope I catch more of those.");
  Wait(1);
  LWeight.Text=String.Format("%d",Weight);
}

function OnFishHooked()
{
  Cod_Bass_Skate(); // Runs Random ints to determine graphic[n]
  cRod.LockView(9);
  cRod.Animate(2,4, eRepeat, eNoBlock, eBackwards);
  cLuke.Say("Look at my rod bending! It must be something big!");
  cRod.LockView(11);
  cRod.Animate(2,4, eRepeat, eNoBlock, eBackwards);
  aREELING.Play();
  cRod.LockView(4);
  cRod.Animate(4,4, eRepeat, eNoBlock, eBackwards);
  cFish1.Move(cFish1.x+190, cFish1.y, eBlock, eWalkableAreas);
  Wait(90);
  oobjectx.Move(oobjectx.X, oobjectx.Y-90, 1, eBlock, eAnywhere);
  oobjectx.Move(oobjectx.X, oobjectx.Y-40,  1, eBlock, eAnywhere);
  cRod.LockView(9);
  cRod.Animate(2,4, eRepeat, eNoBlock, eBackwards);
  aREELING.Stop();
 
  if(object[3].Graphic==84)  // Random int selected in Cod_Bass_Skate()
  {
    WhenGotCod();
  }
  else if(object[3].Graphic==93)  // Random int selected in Cod_Bass_Skate()
  {  
    WhenGotBass();
  } 
  else if(object[3].Graphic==83) // Random int selected in Cod_Bass_Skate()
  {
    WhenGotThornback();
  }
}

function room_RepExec()
{
  if(PPColliding.CWithC(cFish1, cRod) && Hooks==3 && Depths==3 &&
     gCatch.Visible==false && gSetup.Visible==false && (Baits==1 || Baits==2 || Baits==4))
  {
    OnFishHooked(); // handling an actual game event
  }
}

[close]


Now, if you look at every fish event, you may notice that there is basically very little difference between them, and you ended up repeating same bunch commands for three times. Imagine you want to change something in those commands, or add more fish types - you will have to fix same code 3 or more times!
This is very bug prone! But there is a solution: move the similar code to a separate function:
Spoiler

Code: ags

function AfterGotAnyFish()
{
  cRod.UnlockView();
  oobjectx.Transparency=100;
  oobjectx.Move(oobjectx.X, oobjectx.Y+130,  9, eBlock, eAnywhere);
  oobjectx.Transparency=0;
  aREELING.Play();
  Wait(90);
  aREELING.Stop();
  cLuke.Say("I hope I catch more of those.");
  Wait(1);
  LWeight.Text=String.Format("%d",Weight);
}

function WhenGotCod()
{
  cLuke.Say("I've caught a massive Cod!");
  Cod_caught=(Cod_caught +1);
  Cod_Weight();
  AfterGotAnyFish();
}

function WhenGotBass()
{
  cLuke.Say("I've caught a big Bass!");
  Bass_Weight();
  Bass_caught=(Bass_caught +1);
  AfterGotAnyFish();
}

function WhenGotThornback()
{
  cLuke.Say("I've caught a massive Thornback!");
  Skate_caught=(Skate_caught +1);
  Skate_Weight();
  AfterGotAnyFish();
}

[close]
Now you may be sure that regardless of fish type, game does exactly same actions after you got one.

The script could be simplified in a different way too, and possibly even more, but here I just wanted to give an example of consecutive improvement.

Slasher

Hi Crimson,

as polite as ever ;)

It's a wonder I even get a line of script down but you do it with such vigor, such speed (i guess you have 12 fingers).

The way you dealt with it is so clean... here endeth the lesson (I used object ID after scripting them in Global and copied) (laugh)

Thank you so much and yes, it works like a charm (nod)

Cheers mate ;)

slasher




SMF spam blocked by CleanTalk