Help with IF statement (UNSOLVED)

So I have a tricky one here...

I have a guy who you first pay a debt too, after paying him he ask you to go get him some chicken and he will give you a job, but you have to go get something to store things in.

So, I am having a hard time with the if statement, how I have it set up right now... its always checking for the "paid" flag, but if i have the chicken remove the paid flag then the else kicks in and he asks you to go get him chicken again....

Im just trying to figure out how to do tiered quests using flags and if statements.
Thanks for your help!

if (GetBoolean(Mike the dealer, "paid")) {
  msg ("Awesome, now go get my some chicken from the Seven 11 and I will put you to work selling chocolate.")
  if (GetBoolean(Mike the dealer, "haschicken")) {
    if (Got(Choc Case)) {
  msg ("you got the job buddy!")
}
  }
}
else {
  msg ("Where is my money dude?")
}

if you understand the structure/concept of an outline:

I. blah
  A. blah
    i. blah
      a. blah
    ii. blah
      a. blah
  B. blah
II. blah

then hopefully it won't be too difficult to understand 'if' logic design/structure/combinations and its "order of operations"


truth/boolean/logic/"flag" tables:

DEFINITION:

true ---> TRUE
false ---> FALSE

NEGATION (NOT: opposite):

not true ---> FALSE
not false --- TRUE

AND:

true and true ---> TRUE
true and false ---> FALSE
false and true ---> FALSE
false and false ---> FALSE

OR:

true or true ---> TRUE
true or false ---> TRUE
false or true ---> TRUE
false or false ---> FALSE

examples:

boolean_stringlist_variable = NewStringList ()
list add (boolean_stringlist_variable, "true")
list add (boolean_stringlist_variable, "false")

cleaned_room_string_variable = StringListItem (boolean_stringlist_variable, GetRandomInt (0,1))
mowed_lawn_string_variable = StringListItem (boolean_stringlist_variable, GetRandomInt (0,1))

cleaned_room_boolean_variable = false
mowed_lawn_boolean_variable = false

if (cleaned_room_string_variable = "true") {
  cleaned_room_boolean_variable = true
} else {
  cleaned_room_boolean_variable = false
}

if (mowed_lawn_string_variable = "true") {
  mowed_lawn_boolean_variable = true
} else {
  mowed_lawn_boolean_variable = false
}

player.cash_integer_attribute = 0

if (cleaned_room_boolean_variable and mowed_lawn_boolean_variable) {
  player.cash_integer_attribute = player.cash_integer_attribute + 10
  msg ("You get $10 dollars total for doing both chores ($5 for each chore)")
} else if (cleaned_room_boolean_variable or mowed_lawn_boolean_variable) {
  player.cash_integer_attribute = player.cash_integer_attribute + 5
  msg ("You get $5 dollars for doing one of the chores")
} else {
  msg ("You didn't do any chores")
}

msg ("Player Cash: " + player.cash_integer_attribute)

boolean_stringlist_variable = NewStringList ()
list add (boolean_stringlist_variable, "true")
list add (boolean_stringlist_variable, "false")

cleaned_room_string_variable = StringListItem (boolean_stringlist_variable, GetRandomInt (0,1))
mowed_lawn_string_variable = StringListItem (boolean_stringlist_variable, GetRandomInt (0,1))

cleaned_room_boolean_variable = false
mowed_lawn_boolean_variable = false

if (cleaned_room_string_variable = "true") {
  cleaned_room_boolean_variable = true
} else {
  cleaned_room_boolean_variable = false
}

if (mowed_lawn_string_variable = "true") {
  mowed_lawn_boolean_variable = true
} else {
  mowed_lawn_boolean_variable = false
}

player.cash_integer_attribute = 0

if (cleaned_room_boolean_variable and mowed_lawn_boolean_variable) {
  player.cash_integer_attribute = player.cash_integer_attribute + 10
  msg ("You get $10 dollars total for doing both chores ($5 for each chore)")
} else if (cleaned_room_boolean_variable) {
  player.cash_integer_attribute = player.cash_integer_attribute + 5
  msg ("You get $5 dollars for cleaning your room")
} else if (mowed_lawn_boolean_variable) {
  player.cash_integer_attribute = player.cash_integer_attribute + 5
  msg ("You get $5 dollars for mowing the lawn")
} else {
  msg ("You didn't do any chores")
}

msg ("Player Cash: " + player.cash_integer_attribute)

boolean_stringlist_variable = NewStringList ()
list add (boolean_stringlist_variable, "true")
list add (boolean_stringlist_variable, "false")

cleaned_room_string_variable = StringListItem (boolean_stringlist_variable, GetRandomInt (0,1))
mowed_lawn_string_variable = StringListItem (boolean_stringlist_variable, GetRandomInt (0,1))

cleaned_room_boolean_variable = false
mowed_lawn_boolean_variable = false

if (cleaned_room_string_variable = "true") {
  cleaned_room_boolean_variable = true
} else {
  cleaned_room_boolean_variable = false
}

if (mowed_lawn_string_variable = "true") {
  mowed_lawn_boolean_variable = true
} else {
  mowed_lawn_boolean_variable = false
}

player.cash_integer_attribute = 0

if (cleaned_room_boolean_variable or mowed_lawn_boolean_variable) {
  if (cleaned_room_boolean_variable) {
    player.cash_integer_attribute = player.cash_integer_attribute + 5
    msg ("You get $5 dollars for cleaning your room")
  } else if (mowed_lawn_boolean_variable) {
    player.cash_integer_attribute = player.cash_integer_attribute + 5
    msg ("You get $5 dollars for mowing the lawn")
  } else {
    player.cash_integer_attribute = player.cash_integer_attribute + 10
    msg ("You get $10 dollars total for doing both chores ($5 for each chore)")
  }
} else {
  msg ("You didn't do any chores")
}

msg ("Player Cash: " + player.cash_integer_attribute)

etc etc etc

there's (nearly) infinite logic combinations/designs you can do


logic examples (using/having 3 conditions):

(true or true) and false ---> (true) and false ---> FALSE
VS
true or (true and false) ---> true or (false) ---> TRUE


Thanks HK!
Because I am still learning this aspect, I understand the syntax but its the order I am having issues with.
I have Asperger syndrome so some things come super easily and some things are almost impossible unless i find the exact way to interpret it.

Im trying to make sense of what you sent but I have no idea which example might best suit my current situation :(


could you post in words describing what you want? put in words the structure/branching/paths/decisions-consequences that you want? (then we can show the code exquivalent of it)

(or just try to explain better, as at least I couldn't quite understand what exactly you wanted from your OP)

for example

chapter 1:

if do evil deed, goto chapter 2 evil
if do good deed, goto chapter 2 good

chapter 2:

good:

if do bad deed, goto chapter 3 neutral
if do good deed, goto chapter 3 good

bad:

if do bad deed, goto chapter 3 bad
if do good deed, goto chapter 3 neutral

chapter 3:

good: blah
bad: blah
neutral: blah


if you are trying to understand my code examples, you can ignore all of the upper code (as that's just to randomly select 'true' or 'false' values for the 'mowed_lawn_boolean_variable' and 'cleaned_room_boolean_variable' variables, so if we were actually using this code, we'd get different outcomes (seeing the code working in action)

just try to understand the bottom big 'if' block of code

for example:

boolean_stringlist_variable = NewStringList ()
list add (boolean_stringlist_variable, "true")
list add (boolean_stringlist_variable, "false")

cleaned_room_string_variable = StringListItem (boolean_stringlist_variable, GetRandomInt (0,1))
mowed_lawn_string_variable = StringListItem (boolean_stringlist_variable, GetRandomInt (0,1))

cleaned_room_boolean_variable = false
mowed_lawn_boolean_variable = false

if (cleaned_room_string_variable = "true") {
  cleaned_room_boolean_variable = true
} else {
  cleaned_room_boolean_variable = false
}

if (mowed_lawn_string_variable = "true") {
  mowed_lawn_boolean_variable = true
} else {
  mowed_lawn_boolean_variable = false
}

player.cash_integer_attribute = 0

if (cleaned_room_boolean_variable or mowed_lawn_boolean_variable) {
  if (cleaned_room_boolean_variable) {
    player.cash_integer_attribute = player.cash_integer_attribute + 5
    msg ("You get $5 dollars for cleaning your room")
  } else if (mowed_lawn_boolean_variable) {
    player.cash_integer_attribute = player.cash_integer_attribute + 5
    msg ("You get $5 dollars for mowing the lawn")
  } else {
    player.cash_integer_attribute = player.cash_integer_attribute + 10
    msg ("You get $10 dollars total for doing both chores ($5 for each chore)")
  }
} else {
  msg ("You didn't do any chores")
}

msg ("Player Cash: " + player.cash_integer_attribute)

you only need to try to understand the bottom big 'if' block:

(well if you want to understand all of the code, that's perfectly fine too, but all that upper code is just example-demonstration prepping code, for the entire code to work were we to actually use it in a game)

if (cleaned_room_boolean_variable or mowed_lawn_boolean_variable) {
  if (cleaned_room_boolean_variable) {
    player.cash_integer_attribute = player.cash_integer_attribute + 5
    msg ("You get $5 dollars for cleaning your room")
  } else if (mowed_lawn_boolean_variable) {
    player.cash_integer_attribute = player.cash_integer_attribute + 5
    msg ("You get $5 dollars for mowing the lawn")
  } else {
    player.cash_integer_attribute = player.cash_integer_attribute + 10
    msg ("You get $10 dollars total for doing both chores ($5 for each chore)")
  }
} else {
  msg ("You didn't do any chores")
}

Ok I'm sorry I will try to explain better.

The best way I can describe it is this.

It is the "intro" quest to the game.

The player owes a debt, once paying the debt he is sent to get an object to retrieve and give to the debtor.
Upon giving the object to the debtor you are required to return carrying a specific object, once the debtor sees you are carrying said object it will execute the rest of the script saying "you got the job".

As of right now, I have it to the point where I can go to retrieve the final object, but when I return to speak to the debtor it for some reason reverts to the beginning of the code saying "where is my money?".

I'm sorry but I don't know what you mean about the chapter1: bad etc.

EDIT: Ah Im starting to see what you mean now, it was the structure I am having issues with.
I think what is confusing me is should I be using flags for this? Or is this too many steps to be able to use them properly.


okay, here's an example of that in code:

(see if you can understand this, and if not, then ask for help on whatever you don't understand or ask on help on all of it, lol)

<asl version="550">

  <include ref="English.aslx" />
  <include ref="Core.aslx" />

  <game name="EXAMPLE_GAME">

    <attr name="start" type="script">

      invoke (npc.talk)

      player.currency_integer_attribute = 300
      msg ("You magically get $300 !!!")

      invoke (npc.talk)

      invoke (npc.talk)

      food.parent = player
      msg ("You magically got the food")

      invoke (npc.talk)

    </attr>

  </game>

  <object name="room">

    <inherit name="editor_room" />

  </object>

  <object name="food">

    <inherit name="editor_object" />

  </object>

  <object name="player">

    <inherit name="editor_object" />
    <inherit name="editor_player" />

    <attr name="parent" type="object">room</attr>

    <attr name="currency_integer_attribute" type="int">0</attr>

  </object>

  <object name="npc">

    <inherit name="editor_object" />

    <attr name="parent" type="object">room</attr>

    <attr name="debt_integer_attribute" type="int">100</attr>

    <attr name="debt_payed_boolean_attribute" type="boolean">false</attr>

    <displayverbs type="stringlist">

      <value>talk</value>

    </displayverbs>

    <attr name="talk" type="script">

      <![CDATA[

        if (not this.debt_payed_boolean_attribute) { // if you've not payed the debt

          if (player.currency_integer_attribute >= npc.debt_integer_attribute) { // checking if you have enough to pay the debt

            player.currency_integer_attribute = player.currency_integer_attribute - npc.debt_integer_attribute // the debt amount is deducted from your currency amount

            npc.debt_payed_boolean_attribute = true // the 'debt payed' Boolean Attribute's Value is set to 'true'

            msg ("You payed off the debt!")

            msg ("Please get me some food!")

          } else { // if you don't have enough to pay the debt

            msg ("You don't have enough to pay off the debt")

          }

        } else { // if you've payed the debt

          if (Got (food)) { // if you got the food

            msg ("Thanks for the food, you're hired!")

          } else { // if you don't got the food

            msg ("I'm still waiting on you getting me some food")

          }

        }

      ]]>

    </attr>

  </object>

  <verb>
    <property>talk</property>
    <pattern>talk</pattern>
    <defaultexpression>You can't talk to that!</defaultexpression>
  </verb>

</asl>

How about:

if (mike the dealer.paid = true) {
  if (mike the dealer.haschicken = true) {
    if (Got(Choc Case)) {
      msg ("You got the job buddy!")
    }
    else {
      msg ("You need to get a chocolate case")
    }
  }
  else {
    msg ("Awesome, now if you go get me some chicken from the Seven 11,")
    msg(" I will put you to work selling chocolate.")
  }
}
else {
  msg ("Where's my money, dude.")
}

Ha, took me so long to write this code, you guys had a full conversation.
It only tells the player where they are in the quest when the player speaks to Mike the dealer.
All the dealer attributes must start out as false at game start.


it takes awhile to train your brain in this 'if'/coding type of logic... it's not natural... and logic is an advanced mathematical science, so it's not easy (this is known as "symbolic logic" in Philosophy which programming/coding is using too with its boolean logic and boolean algebra)

and then there's the learning of just the code syntax/structure (how you write the code correctly)

and the "order of operations" can get really tricky... really try to use the concept of an outline... it'll help you understand the code and what it's doing better...


https://philosophy.lander.edu/logic/symbolic.html

https://en.wikipedia.org/wiki/Truth_table

https://www.electronics-tutorials.ws/boolean/bool_1.html
https://www.electronics-tutorials.ws/boolean/bool_2.html
https://www.electronics-tutorials.ws/boolean/bool_3.html
https://www.electronics-tutorials.ws/boolean/bool_6.html
https://www.electronics-tutorials.ws/boolean/bool_7.html
https://www.electronics-tutorials.ws/boolean/bool_8.html

https://www.arl.wustl.edu/~jst/cse/260/ddcPrint.pdf

https://www.khanacademy.org/computing/computer-programming/programming/logic-if-statements/a/review-logic-and-if-statements (click on the other various topics/lessons on the left)

https://www.codecademy.com (got to register, but its free. step by step lessons of various programming stuff, from beginner/new/never-coded to some more advanced stuff)


Quest's Data Types:

Strings: a collection of characters/letters/alphabet/numbers/symbols, aka 'text'
Integers: non-decimal amounts
Doubles: decimal amounts
Booleans ("flags"): true/false
Objects: an Object reference/pointer
Scripts: actions/events
Lists: a collection of items
Dictionaries: a collection of inputs-outputs


technically, all data types are 'indicators/flags', but "flags" are usually used in reference to booleans (true/false) and/or their integer equivalents (1/0) dealing with circuitry and logic gates and machine programming and low-level programming and also the internet with the data/code packets being sent back and forth

(true:on:yes:1 / false:off:no:0)


It's so frustrating because I can build web apps for days, but this is so foreign to me lol.
Basically it all comes down to WHERE I am putting the ifs, elses and else ifs... those sneaky bwords.
If I'm not too far off the mark I'm pretty sure that's what you guys are saying.

Each new level of the "quest" would go into a different else branch seperate from the other things?

If thats correct.. then should I be using flags?
As of right now, I have a flag set when I pay the debt, and one set when I give the chicken.
Or do these ifs elses and etc negate the need for flags?

ps, I really appreciate the help lol


If you've got multiple stages which have to be done in order, it might be worth putting them in the script in reverse order. It keeps your code flat, and may be more efficient (and also means you don't have to think about it so much - there's a straightforward rule to follow).

So in this case, it might look something like:

if (GetBoolean (Mike the dealer, "givenjob")) {
  msg ("I gave you a job. Why aren't you doing it?")
}
else if (Got (Choc case)) {
  msg ("Well done! You got the job!")
  Mike the dealer.givenjob = true
}
else if (GetBoolean (Mike the dealer, "haschicken")) {
  msg ("I'll give you a job, but you need a choc case first")
}
else if (GetBoolean(Mike the dealer, "askedforchicken") and Got (chicken)) {
  msg ("That my chicken? Now {command:give chicken to mike:give it to me} and I'll give you a job.")
}
else if (GetBoolean(Mike the dealer, "askedforchicken")) {
  msg ("Come on, dude! Get me my chicken")
}
else if (GetBoolean (Mike the dealer, "paid")) {
  msg ("Awesome, now go get me some chicken from the Seven 11 and I will put you to work selling chocolate.")
  Mike the dealer.askedforchicken = true
}
else {
  msg ("Where is my money dude?")
  if (player.money >= 50) {
    msg ("You give Mike his money")
    player.money = player.money - 50
    Mike the dealer.paid = true
  }
}

Quest goes through all the tiers of the quest starting with the highest, until it finds one that the player has reached.


Oh man! I had such a feeling thats all I was going wrong was misunderstanding the structure of the statements!
One final question, is your (mike the dealer, paid) a flag or an attribute?


A flag is just an attribute whose value is true or false. You can use any kind of attribute you want to keep track of which mission(s) the player has done.


SO at the end of the day, the only thing I was screwing up is the heirarchy of the if branches lol
#newbsftw

I will put this to practice tonight :D Thank you mrangel sir.


Ok so i set this all up in a test copy of my game.

It gets as far as me returning with chicken, but it seems that its not recognizing that I am carrying the chicken, as its like "come on dude wheres my chicken?"

All attributes are turned on in the debugger, it just doesnt seem to see that i have that object.


Have you seen this line run in your game?

else if (GetBoolean(Mike the dealer, "askedforchicken") and Got (chicken)) {
  msg ("That my chicken? Now {command:give chicken to mike:give it to me} and I'll give you a job.")

You have to run scripts for the command hyper link "give chicken to mike". the give it to me is what prints on the screen. The "give chicken to mike" is the command you have to make.


I'm assuming it's the Got (chicken) which is failing.
Is the chicken in the player's inventory? Or are you using some other way of dealing with it?


the chicken is in the inventory as I go buy it from a shop.
But when I return he still asks wheres my chicken? lol


(filler for getting my edited post, updated/posted)


ah... (we got a missing attribute setting in mrangel's code, unless the 'give chicken to mike' Command handles this already)

here's the corrected code:

if (GetBoolean (Mike the dealer, "givenjob")) {
  msg ("I gave you a job. Why aren't you doing it?")
}
else if (Got (Choc case)) {
  msg ("Well done! You got the job!")
  Mike the dealer.givenjob = true
}
else if (GetBoolean (Mike the dealer, "haschicken")) {
  msg ("I'll give you a job, but you need a choc case first")
}
else if (GetBoolean(Mike the dealer, "askedforchicken") and Got (chicken)) {
  msg ("That my chicken? Now {command:give chicken to mike:give it to me} and I'll give you a job.")



  Mike the dealer.haschicken = true // <--- (this is the added fix, but it should be in/done-by the 'give chicken to mike' Command)



}
else if (GetBoolean(Mike the dealer, "askedforchicken")) {
  msg ("Come on, dude! Get me my chicken")
}
else if (GetBoolean (Mike the dealer, "paid")) {
  msg ("Awesome, now go get me some chicken from the Seven 11 and I will put you to work selling chocolate.")
  Mike the dealer.askedforchicken = true
}
else {
  msg ("Where is my money dude?")
  if (player.money >= 50) {
    msg ("You give Mike his money")
    player.money = player.money - 50
    Mike the dealer.paid = true
  }
}

Thank you that code works perfectly... to the point where I return with the choc case and he offers me a job but i need a choc case again...
I think im missing something big here :S


there shouldn't be a problem:

if (GetBoolean (Mike the dealer, "givenjob")) {
  msg ("I gave you a job. Why aren't you doing it?")
}
else if (Got (Choc case)) {
  msg ("Well done! You got the job!")
  Mike the dealer.givenjob = true
}

as the 'Mike the dealer.givenjob = true' causes the next time the scripting runs, to meet the first check 'if (GetBoolean (Mike the dealer, "givenjob")) {' and thus it does its script of 'msg ("I gave you a job. Why aren't you doing it?")'

did you try to insert some kind of job effect into the scripting? maybe you just inserted it into the wrong place? if you inserted a job effect into the scripting, can you post the scripting, as it might be just a matter of wrong placement within the scripting and its "order of operations" of 'if/else-if/else' checks


All I did was add the attributes to "Mike the dealer" that follow the code, set them to Boolean/false.
I was able to get part of it working by following the above advice and adding the "has chicken = true" to the give chicken command.

From then, the way its set up based on the proper code, I go buy the choc case, return with it in my inventory and it still asks me to go get the choc case.

(I have changed certain words to be family friendly in the forums)

I will post the code with the family friendly changes (only the names of two objects).

Mike the dealer:

  if (GetBoolean (Mike the dealer, "givenjob")) {
 msg ("I gave you a job. Why aren't you doing it?")
}
else if (Got (choc case)) {
  msg ("Well done! You got the job!")
  Mike the dealer.givenjob = true
}
else if (GetBoolean (Mike the dealer, "haschicken")) {
  msg ("I'll give you a job, but you need a choc case first")
}
else if (GetBoolean(Mike the dealer, "askedforchicken") and Got (chicken)) {
  msg ("That my chicken? Now {command:give chicken to mike:give it to me} and I'll give you a job.")
}
else if (GetBoolean(Mike the dealer, "askedforchicken")) {
  msg ("Come on, dude! Get me my chicken")
}
else if (GetBoolean (Mike the dealer, "paid")) {
  msg ("Awesome, now go get me some chicken from the Seven 11 and I will put you to work selling chocolate.")
  Mike the dealer.askedforchicken = true
}
else {
  msg ("Where is my money dude?")
  if (player.money >= 50) {
    msg ("You give Mike his money")
    player.money = player.money - 50
    Mike the dealer.paid = true
  }
}

Give chicken command:

Mike the dealer.haschicken = true

Is the issue with the "got (choc case) script?
Doesn't this check if it is currently in my inventory?
Because it certainly is there when it tells me to go buy it again.


Bump? <3


After spending a bunch of time looking at the code, ive realized that the code is in a loop.
When I return with the case, even though its in my inventory, because the attribute "haschicken" is true, its running that code first.
Thus not letting me access the next branch of the code...

is this correct?


For some reason, quest is bypassing...

else if (Got (choc case)) {

...because it's not seeing "choc case" in the inventory. Are you sure that it's there and visible, and not in a non-transparent container? You can check the "Debugger" tool in-game and make sure that the parent attribute of "choc case" is indeed the player.

Does the object named "choc case" (name, not alias) in the player's inventory exactly match "choc case" in the code, including caps/spaces/etc.?


Yes, the choc case is in the inventory, it is not transparent and is closed.
The parent of the case after purchasing the case, is the player.
But still when I return with the case in my inventory, he tells me to go get the case.

I tried changing the code to be "if mike the dealer has chicken AND player has case then= you got the job! but that didnt work either.

EDIT: Ok, well for some reason, the case shows up in my inventory when the parent object is still stock1 from the setupshop script.


If you're using the shop, it gives the player a clone of the purchased item. In that case, you'll have to replace Got (choc case) with:
ListCount (FilterByAttribute (ScopeInventory(), "prototype", choc case)) > 0).

That checks if the player has a clone of a given object. Think I got that right, but it's hard to type code on my phone.


Oh man, thank you!!! It finally works :)
I'm sorry that was such a pain lol

Now, one last question.
How do I remove the chicken clone from my inventory when I give it to Mike the dealer?


wow... I would have never have known/found/realized the issue to be due to using pixie's 'shop' library... making+using a clone object, which is why the 'Got (choc case)' isn't working as it's not using your 'choc case' Object, but a clone Object of it, as the Object that it puts into your inventory (it never puts the 'choc case' Object into the inventory, hence the 'Got (choc case)' fails as there's no 'choc case' Object within the inventory for it to find, lol)... nice job mrangel!


How do I remove the chicken clone from my inventory when I give it to Mike the dealer?

The shop might also allow the player to buy multiple choc cases.

  1. If you want to remove all of them from the inventory, you'd want something like:
foreach (obj, FilterByAttribute (ScopeInventory(), "prototype", choc case)) {
 destroy (obj.name)
}
  1. If you only want to remove one clone, then it would be:
obj = PickOneObject(FilterByAttribute (ScopeInventory(), "prototype", choc case))
destroy (obj.name)

You could also do RemoveObject (choc case) to stop the shop selling any more.


This topic is now closed. Topics are closed after 60 days of inactivity.

Support

Forums