RunUO Community

This is a sample guest message. Register a free account today to become a member! Once signed in, you'll be able to participate on this site by adding your own topics and posts, as well as connect with other members through your own private inbox!

Lucid's Archery -Won't fire from quiver

daat99

Moderator
Staff member
That's correct, now let's get back on topic:
Code:
                  //end of change
                  if( attacker.Player &&
                      ( quiver == null || !quiver.ConsumeTotal( AmmoType, 1 ) ) &&
                      (  pack == null ||  !pack.ConsumeTotal( AmmoType, 1 ) ) )
                                Console.WriteLine("Returning false because not consuming");
                        return false;
What happens if the condition is true and what happens if the condition is false?
 

daat99

Moderator
Staff member
No, look again.
Try to replace the long lines with shorter lines in a new notepad(++) file.
For example replace the if statement itself which is this long line:
Code:
if( attacker.Player &&
                      ( quiver == null || !quiver.ConsumeTotal( AmmoType, 1 ) ) &&
                      (  pack == null ||  !pack.ConsumeTotal( AmmoType, 1 ) ) )
With a shorter line:
Code:
if ( condition )
Now you'll get the code:
Code:
                  //end of change
                  if ( condition )
                                Console.WriteLine("Returning false because not consuming");
                        return false;
What this code does when condition is true and what does it do when condition is false?

PS
Try to read the links I posted again to make sure you understand how if statements works.
 

daat99

Moderator
Staff member
I'm a bit confused because I don't see any code that "consumes" stuff in there :(

Let's try this code:
Code:
                //end of change
                  if ( condition )
                                doA();
                        doB();
When condition is True will it do A, B, both or neither?
When condition is False will it do A, B, both or neither?
 

daat99

Moderator
Staff member
Lets look back at this post:
True.
With that in mind what will it print on the console?
Code:
if ( condition == true )
    Console.WriteLine("condition is true");
    Console.WriteLine("2nd print");
Console.WriteLine("Done");
When the condition is true you stated correctly that:
I don't know. When it's true the console should display
Code:
condition is true
2nd print
Done


When the condition is false you also stated correctly that:
So, it would write
Code:
2nd print
Done
? That's kinda stupid :confused: I'll stick to the brackets.

Can you compare the original code and the new code and see how it should react (knowing the correct answers to the original code that is)?
 

daat99

Moderator
Staff member
That's correct so when we look back at our code (with the shortened condition):
Code:
                  //end of change
                  if ( condition )
                                Console.WriteLine("Returning false because not consuming");
                        return false;
Is there any scenario where the "return false" line won't be executed?
 
Oh, I should have told you. About a week ago, I put my old version back in, an changed the base ranged to read the quiver. XD sorry. But as a response, I don't believe there is a reason for it not to "return false"
 

daat99

Moderator
Staff member
It doesn't matter that you use another code, let's keep learning :)

In your earlier post regarding this code:
Code:
        public virtual bool OnFired( Mobile attacker, Mobile defender )
        {
                Console.WriteLine("OnFired started.");
            //--<<Advanced Archery Edit>>---------------------[Start 3/4]
            PlayerMobile a_pm = attacker as PlayerMobile;
            Container pack = attacker.Backpack;
            BaseQuiver quiver = attacker.FindItemOnLayer( Layer.MiddleTorso ) as BaseQuiver;
            BaseRangedModule module = this.BaseRangedModule;
 
            if ( !module.HasBowString )
            {
                if ( DateTime.Now >= m_NextStringWarning )
                {
                    m_NextStringWarning = DateTime.Now + StringWarningDelay;
                    attacker.SendMessage( "You need a string to use this bow. See a local fletcher to apply the string." );
                    return false;
                }
                else
                {
                        Console.WriteLine("Returning false because {0}", "String is null");
                        return false;
                }
            }
           
            if ( Ammo == null )
            {
                if ( DateTime.Now >= m_NextAmmoWarning )
                {
                    m_NextAmmoWarning = DateTime.Now + AmmoWarningDelay;
                    attacker.SendMessage( "You are out of ammo." );
                        Console.WriteLine("Returning false because there is no ammo");
                    return false;
                }
                else
                {
                        Console.WriteLine("Returning false because {0}", "Ammo is null");
                        return false;
                }
            }
           
            if( attacker.Player && quiver != null && quiver.LowerAmmoCost > Utility.Random( 100 ) )
            {
                attacker.MovingEffect( defender, EffectID, 18, 1, false, false );
                        Console.WriteLine("Returning true because quiver.lowerammocost.");
                return true;
            }
//NEWEST EDIT
                  if ( quiver != null )
                  {
                            Item[] typedItems = quiver.FindItemsByType( typeof( LightningArrow ), true );
                            Console.WriteLine("FindItemsByType was able to find {0} items.", typedItems.Length); //try Count if it doesn't compile
                            if ( typedItems.Length > 0 )
                          {
                            Console.WriteLine("The amount of the first item is: {0}", typedItems[0].Amount);
                            typedItems[0].Consume( 1 );
                            Console.WriteLine("The amount of the first item after consuming 1 is: {1}", typedItems[0].Amount);
                          }
                  }
                  else
                  {
                      Console.WriteLine("the quiver is null");
                  }
                  //end of change
                  if( attacker.Player &&
                      ( quiver == null || !quiver.ConsumeTotal( AmmoType, 1 ) ) &&
                      (  pack == null ||  !pack.ConsumeTotal( AmmoType, 1 ) ) )
                                Console.WriteLine("Returning false because not consuming");
                        return false;
 
            //--<<Advanced Archery Edit>>---------------------[End 3/4]
       
        if ( attacker.Player )
            {
                //BaseQuiver quiver = attacker.FindItemOnLayer( Layer.Cloak ) as BaseQuiver;
                //Container pack = attacker.Backpack;
 
                if ( quiver == null || Utility.Random( 100 ) >= quiver.LowerAmmoCost )
                {
                    if ( quiver != null && quiver.ConsumeTotal( AmmoType, 1 ) )
                        quiver.InvalidateWeight();
                    else if ( pack == null || !pack.ConsumeTotal( AmmoType, 1 ) )
            Console.WriteLine("returning false because quiver != null");
                        return false;
                }
                else if ( quiver.FindItemByType( AmmoType ) == null && ( pack == null || pack.FindItemByType( AmmoType ) == null ) )
                {
                    // lower ammo cost should not work when we have no ammo at all
            Console.WriteLine("returning false because ammo");
                    return false;
                }
            }
 
            attacker.MovingEffect( defender, EffectID, 18, 1, false, false );
                        Console.WriteLine("Returning true because Moving Effect");
 
            return true;
        }
You stated:
As it is, it's not shooting. It's consuming, but it's not shooting. Before I could use normal arrows, now it won't shoot at all. What could we have done to stop the bows from shooting?
Now lets read this code more closely.
Your code consumes the arrow because the "ConsumeTotal" (from quiver) in this section:
Code:
                  if( attacker.Player &&
                      ( quiver == null || !quiver.ConsumeTotal( AmmoType, 1 ) ) &&
                      (  pack == null ||  !pack.ConsumeTotal( AmmoType, 1 ) ) )
                                Console.WriteLine("Returning false because not consuming");
                        return false;
The condition is translated to "false" because the arrow was consumed so it doesn't print the message "returning false because not consuming".
However, as we just saw it'll ALWAYS return false regardless of the condition.

How would you change these 3 lines of code so it'll both print the "returning false because not consuming" and actually return false only when it is not consuming?
 

daat99

Moderator
Staff member
Lets explore that solution:
Code:
                  if( attacker.Player &&
                      ( quiver == null || !quiver.ConsumeTotal( AmmoType, 1 ) ) &&
                      (  pack == null ||  !pack.ConsumeTotal( AmmoType, 1 ) ) )
                                return false;
                       Console.WriteLine("Returning false because not consuming");
For simplicity, let's name the "return false" as command "A" and the console write as command "B"

1. Which commands will be executed when the condition is true?
2. Which commands will be executed when the condition is false?
 

daat99

Moderator
Staff member
When false you are correct.
When true you were close.

Lets examine the code:
When the condition is true the code will continue to execute command A.
Now let's remember that command A is "return false".
This means "stop executing the rest of the method and simply tell the person that called us the answer is NO.
As a result of that command B will not be executed at all (we stopped executing the method in the middle).

So if we'll recap:
Our condition partially indicates if we were able to consume the arrow.
Our method was called because someone wanted to know if we are "firing" an arrow.

If the condition is true (we weren't able to consume an arrow) we tell the caller that we are NOT firing an arrow (returning false).
If the condition is false however (meaning we were able to consume the arrow) we print a message to the console stating "Returning false because not consuming" - but we did consume the arrow and we aren't returning false???

So changing the order of the lines won't fix the issue.

How will you fix this 3 lines of code to work as intended without deleting any of them?
Code:
                  if( attacker.Player &&
                      ( quiver == null || !quiver.ConsumeTotal( AmmoType, 1 ) ) &&
                      (  pack == null ||  !pack.ConsumeTotal( AmmoType, 1 ) ) )
                                Console.WriteLine("Returning false because not consuming");
                        return false;
Hint:
Refer to the articles I linked in our earlier posts to see how if statements work and how to fix it.
 
Top