Exit Function

Is there an Exit Function feature? I have a function that checks a player's stamina and if they are dead they are moved to another room which acts as my Game Over. But, even though it send my player there it seems like the program is still following the chain of logic. For instance:

Room 1000
script: modifystamina -5 <-- this is a function where I pass the amount to
if the function completes then the script moves the player to Room 2000

modifystamina
script: this checks to see if player's stamina is 0. If so it moves the player to Game Over room and does Finish Game.

But, even though I move the player to the game over room, the function still finishes out and the player ends up in room 2000 with the game finishing.


The script that's currently running will always finish. If you want the script to move the player to room 2000 or not depending on whether they're still alive, then you need an if statement to check that.


You want to exit a function? Use the return statement: http://docs.textadventures.co.uk/quest/scripts/return.html


That would work. How do I test the value of a return statement? Say the following:

if (modifystamina (-5) = "Dead" ) {
}
else {
MoveObject (player, Entry 2399)
}

That doesn't work. How would I do it?


this is a bit of code overkill/redundant checking, but did it so you can see what you can do with scripting

<!--
The, type="XXX", in the Function's signature/header (first/top) line specifies the return value's type. Your return value's type must match up with whatever the return type you specify in the Function's signature/header
-->

<function name="add_two_integer_function" parameters="integer_1_parameter,integer_2_parameter" type="int">
  if (TypeOf (integer_1_parameter) = "int" and TypeOf (integer_2_parameter) = "int") {
    return (integer_1_parameter + integer_2_parameter)
  } else {
    msg ("wrong inputs for your function's arguments/parameters")
    return (0)
  }
</function>

// ---------------------------------

// scripting example using this example function:

example_variable = add_two_integer_function (15, 5)

if (TypeOf (example_variable) = "int") {
  if (not example_variable = 0) {
    msg ("Sum of adding two integers: " + example_variable)
  } else {
    msg ("either: wrong inputs for your function's arguments/parameters or your two integers added together indeed results in a sum of zero")
  }
} else {
  msg ("return value isn't an integer")
}

Ok. So what is wrong with this?

Room 1000:
script:

if (modifystamina (-5) = -99) {
  MoveObject (player, Game Over)
}
wait {
  MoveObject (player, Entry 2399)
}

Function modifystamina:

if (player.staminacurrent > player.staminamax) {
  player.staminacurrent = player.staminamax
}
if (player.staminacurrent < 1 ) {
  if (ListCount (game.playerskills) = 1) {
    return (-99)
  }
  msg ("You have been knocked unconcious. You must choose a skill to disable.")
  show menu ("Pick a skill to disable:", game.playerskills, true) {
    list remove (game.playerskills, result)
    list add (game.disabledskills, result)
    player.Skills = ListItem(game.playerskills, 0)
    for (N, 1, ListCount(game.playerskills), 1) {
      player.Skills = player.Skills + ", " + ListItem (game.playerskills, N)
    }
    player.disabledskills = ListItem(game.disabledskills, 0)
    for (N, 1, ListCount(game.playerskills), 1) {
      player.disabledskills = player.disabledskills + ", " + ListItem (game.disabledskills, N)
    }
    player.staminacurrent = 1
  }
}
player.Stamina = player.staminacurrent + "/" + player.staminamax
}

It keeps saying function doesnt return a value, the wait from the room script is going off at the same time as the showmenu and it's locking up. I get this alot. I'm sure it's an order thing but not sure how to fix it.


K.V.

That function only returns a value if playerstaminacurrent is less than 1.

It must be greater than or equal to 1 when that function is being called, so it isn't returning anything.

If you set a function to return a value, it must return a value, no matter what, or Quest will throw an error.


Can you copy that function from full code view and paste that here? (That will show your paramaters and your return type, which will also help.)


Well, I have the error fixed. Just stuck return (1) before the last line. But, I am still having the issue that the ShowMenu is going off but the program is not waiting for a response before it continues running and it locks it up. The menu, I can scroll up and down through the choices, but when I hit enter nothing happens. Grr.


K.V.

If you paste some code, I'm sure one of us can fix you up.


Well, not sure what part to post. But I would assume it's just the room and the function that I posted above. But here it is again with the fixes from above:

Script from room Entry 1099:

msg ("You take 5 points of stamina damage!")
if (modifystamina (-5) = -99) {
  MoveObject (player, Game Over)
}
wait {
  MoveObject (player, Entry 2399)
}

Script from function modifystamina:

</function>
]]  <function name="modifystamina" parameters="modifier" type="int"><![CDATA[
    player.staminacurrent = player.staminacurrent + modifier
    if (player.staminacurrent > player.staminamax) {
      player.staminacurrent = player.staminamax
    }
    if (player.staminacurrent < 1 ) {
      if (ListCount (game.playerskills) = 1) {
        return (-99)
      }
      msg ("You have been knocked unconcious. You must choose a skill to disable.")
      show menu ("Pick a skill to disable:", game.playerskills, true) {
        list remove (game.playerskills, result)
        list add (game.disabledskills, result)
        player.Skills = ListItem(game.playerskills, 0)
        for (N, 1, ListCount(game.playerskills), 1) {
          player.Skills = player.Skills + ", " + ListItem (game.playerskills, N)
        }
        player.disabledskills = ListItem(game.disabledskills, 0)
        for (N, 1, ListCount(game.playerskills), 1) {
          player.disabledskills = player.disabledskills + ", " + ListItem (game.disabledskills, N)
        }
        player.staminacurrent = 1
      }
    }
    return (1)
    player.Stamina = player.staminacurrent + "/" + player.staminamax
  ]]></function>

K.V.

You're using game.playerskills as the list for show menu.

Then, you're removing something from that same list from inside the script.

I don't think you can do that, but I'm not 100% sure.

Try this:

      show menu ("Pick a skill to disable:", game.playerskills, true) {
        game.playerskilltoremove = result
        list add (game.disabledskills, result)
        player.Skills = ListItem(game.playerskills, 0)
        for (N, 1, ListCount(game.playerskills), 1) {
          player.Skills = player.Skills + ", " + ListItem (game.playerskills, N)
        }
        player.disabledskills = ListItem(game.disabledskills, 0)
        for (N, 1, ListCount(game.playerskills), 1) {
          player.disabledskills = player.disabledskills + ", " + ListItem (game.disabledskills, N)
        }
        player.staminacurrent = 1
      }
      list remove (game.playerskills, game.playerskilltoremove)
      game.playerskilltoremove = null

added this to get post to go through


Well, the only problem with that is that I need to remove the skill from game.playerskills before I rebuild the list with the for/next statement in the first part of that. So I tried this:

player.staminacurrent = player.staminacurrent + modifier
if (player.staminacurrent > player.staminamax) {
  player.staminacurrent = player.staminamax
}
if (player.staminacurrent < 1 ) {
  if (ListCount (game.playerskills) = 1) {
    return (-99)
  }
  msg ("You have been knocked unconcious. You must choose a skill to disable.")
  show menu ("Pick a skill to disable:", game.playerskills, true) {
    player.skilltoremove = result
    list add (game.disabledskills, result)
    player.disabledskills = ListItem(game.disabledskills, 0)
    for (N, 1, ListCount(game.playerskills), 1) {
      player.disabledskills = player.disabledskills + ", " + ListItem (game.disabledskills, N)
    }
  }
  player.staminacurrent = 1
  list remove (game.playerskills, player.skilltoremove)
  player.Skills = ListItem(game.playerskills, 0)
  for (N, 1, ListCount(game.playerskills), 1) {
    player.Skills = player.Skills + ", " + ListItem (game.playerskills, N)
  }
}
return (1)
player.Stamina = player.staminacurrent + "/" + player.staminamax

And got this error:
Error running script: Error evaluating expression 'player.Skills + ", " + ListItem (game.playerskills, N)': ListItem: index 5 is out of range for this list (5 items, last index is 4)

And I still don't get how it's going to the wait function in the room before it finishes getting the result from the menu. It's like it's running everything at once instead of what I feel should be logical:

Room Description
msg - You take 5 points of damage
run modifystamina function
wait for any key
move player to entry 2399

Instead its going

Room Description
msg- You take 5 points of damage
wait for any key
modifystamina (which shows the menu)
and locks up


K.V.

In place of this:

for (N, 1, ListCount(game.playerskills), 1) {
    player.Skills = player.Skills + ", " + ListItem (game.playerskills, N)
  }

Try:

foreach(N,game.playerskills) {
    player.Skills = player.Skills + ", " + N
  }

Unless you don't want the first item on the list included. (The first item on the list is 0, and you have 1. The last item on the list is ListCount(list)-1 (because the first one is 0). )

If you want to skip the first item, try:

for (N, 1, ListCount(game.playerskills)-1, 1) {
    player.Skills = player.Skills + ", " + ListItem (game.playerskills, N)
  }

Example:

list = Split("one;two;three;four;five",";")
for (N, 1, ListCount(list)-1, 1) {
  msg (ListItem(list,N))
}

Prints:

two
three
four
five


list = Split("one;two;three;four;five",";")
for (N, 0, ListCount(list)-1, 1) {
  msg (ListItem(list,N))
}

one
two
three
four
five


list = Split("one;two;three;four;five",";")
foreach(N, list){
  msg (N)
}

one
two
three
four
five


http://docs.textadventures.co.uk/quest/scripts/for.html

http://docs.textadventures.co.uk/quest/scripts/foreach.html


Well, I was doing that because I was creating a custom string. The first entry is before the For statement:

player.disabledskills = ListItem(game.disabledskills, 0)

Then the for statement adds that entry along with a comma then the next item in the list. Thus, you get a single string of the players skills with commas separating them.


K.V.

I see.

(Sorry, I just realized I'm getting sleepy.)

How about this:

player.staminacurrent = player.staminacurrent + modifier
if (player.staminacurrent > player.staminamax) {
  player.staminacurrent = player.staminamax
}
if (player.staminacurrent < 1 ) {
  if (ListCount (game.playerskills) = 1) {
    return (-99)
  }
  msg ("You have been knocked unconcious. You must choose a skill to disable.")
  show menu ("Pick a skill to disable:", game.playerskills, true) {
    player.result_skill = result
  }
  list remove (game.playerskills, player.result_skill)
  list add (game.disabledskills, player.result_skill)
  player.result_skill = null
  player.disabledskills = ListItem(game.disabledskills, 0)
  for (N, 1, ListCount(game.playerskills)-1, 1) {
    player.disabledskills = player.disabledskills + ", " + ListItem (game.disabledskills, N)
  }
  player.staminacurrent = 1
  player.Skills = ListItem(game.playerskills, 0)
  for (N, 1, ListCount(game.playerskills), 1) {
    player.Skills = player.Skills + ", " + ListItem (game.playerskills, N)
  }
}
return (1)
player.Stamina = player.staminacurrent + "/" + player.staminamax

Jesus this thing is pissing me off. Why is it so difficult?? Your method has everything going off before it gets the input from the show menu. I put a msg to display the game.playerskills. If I put all that code outside of the show menu, it goes off before getting the menu input. If I put it inside the showmenu it never goes off. WTH?!


K.V.

Sorry. I was much more tired than I realized.

msg ("You take 5 points of stamina damage!")
if (modifystamina (-5) = -99) {
  MoveObject (player, Game Over)
}
else {
  SetTurnTimeout (1) {
    wait {
      MoveObject (player, Entry 2399)
    }
  }
}
player.staminacurrent = player.staminacurrent + modifier
if (player.staminacurrent > player.staminamax) {
  player.staminacurrent = player.staminamax
}
if (player.staminacurrent < 1 ) {
  if (ListCount (game.playerskills) = 1) {
    return (-99)
  }
  msg ("You have been knocked unconcious. You must choose a skill to disable.")
  list = ListExclude(game.playerskills, "XxYyZzYy")
  ShowMenu ("Pick a skill to disable:", list, true) {
    list remove (game.playerskills, result)
    list add (game.disabledskills, result)
    player.Skills = ListItem(game.playerskills, 0)
    for (N, 1, ListCount(game.playerskills)-1, 1) {
      player.Skills = player.Skills + ", " + ListItem (game.playerskills, N)
    }
    player.disabledskills = ListItem(game.disabledskills, 0)
    for (N, 1, ListCount(game.playerskills)-1, 1) {
      player.disabledskills = player.disabledskills + ", " + ListItem (game.disabledskills, N)
    }
    player.staminacurrent = 1
  }
}
player.Stamina = player.staminacurrent + "/" + player.staminamax
return (1)

Ok. So got the menu working now. It doesn't lock up. But for some reason, none of the code inside of the show menu is working. (Oh and I needed to put the last line before return (1) or the player.Stamina never updated.


K.V.
  player.disabledskills = ListItem(game.disabledskills, 0)
    for (N, 1, ListCount(game.playerskills)-1, 1) {
      player.disabledskills = player.disabledskills + ", " + ListItem (game.disabledskills, N)
    }

I don't understand this bit.

You are adding each skill from game.playerskills to the string player.disabledskills, except for the first list item on game.playerskills?


No. The player gets knocked unconscious when his stamina drops below 0 and is required to choose one of his skills to disable and he is returned to 1 stamina. So...

msg ("You have been knocked unconcious. You must choose a skill to disable.")
// Below is the list of the players active skills
list = game.playerskills
// Show a menu of those skills and have player choose one
ShowMenu ("Pick a skill to disable:", list, true) {
// Remove that skill from his active skills
list remove (game.playerskills, result)
// Add that skill to the list of disabled skills
list add (game.disabledskills, result)
// Recreate the Status Box line that displays the players active skills
// The line below is the first active skill (For example: Archery)
player.Skills = ListItem(game.playerskills, 0)
// The below for loop will now add the other active skills with a comma before each item (For example: , Agility, Brawling
for (N, 1, ListCount(game.playerskills)-1, 1) {
player.Skills = player.Skills + ", " + ListItem (game.playerskills, N)
}
// So when it's done player.Skills show "Archery, Agility, Brawling"
// Same with below except with disabled skills
player.disabledskills = ListItem(game.disabledskills, 0)
for (N, 1, ListCount(game.playerskills)-1, 1) {
player.disabledskills = player.disabledskills + ", " + ListItem (game.disabledskills, N)
}


K.V.

EDIT

I posted this as you were posting your last post, so I didn't see you break it down for me.


To make sure I'm understand what you're goal is:


If you subtract 5 from player.staminacurrent, and that makes player.staminacurrent less than 1, and if the player only has one skill on game.playerskills:

  • then you want to finish the game.

Otherwise, if you subtract 5 from player.staminacurrent, and if player.staminacurrent is 1 or more:

  • you make the player disable a skill
  • then you want to remove that skill from game.playerskills
  • then you want to add that skill to a list (game.disabledskills) and to a string (player.disabledskills)
  • then you want to make player.Skills a string that displays all of the current skills
  • then you want to set player.staminacurrent to 1
  • then make player.Stamina show CURRENT STAMINA/MAX STAMINA.

Almost. Right on the first one.

Otherwise, if you subtract 5 from player.staminacurrent, and if player.staminacurrent is 0 or less:

you make the player disable a skill
then you want to remove that skill from game.playerskills
then you want to add that skill to a list (game.disabledskills)
then you want to make player.disabledskills a string that display all of the disabled skills
then you want to make player.Skills a string that displays all of the current skills
then you want to set player.staminacurrent to 1
then make player.Stamina show CURRENT STAMINA/MAX STAMINA.

K.V.

Okay.

I have changed show menu to ShowMenu, along with a few other things.

For instance, I did away with the for scripts and just joined the lists.

player.staminacurrent = player.staminacurrent + modifier
if (player.staminacurrent > player.staminamax) {
  player.staminacurrent = player.staminamax
}
if (player.staminacurrent < 1 ) {
  if (ListCount (game.playerskills) = 1) {
    return (-99)
  }
  msg ("You have been knocked unconcious. You must choose a skill to disable.")
  list = ListExclude(game.playerskills, "XxYyZzYy")
  ShowMenu ("Pick a skill to disable:", list, true) {
    list remove (game.playerskills, result)
    list add (game.disabledskills, result)
    player.Skills = Join(game.playerskills,",")
    if (HasAttribute(game,"debugging")) {
      if (game.debugging) {
        msg ("DEBUGGING: player.Skills = "+player.Skills)
      }
    }
    player.disabledskills = Join(game.disabledskills,",")
    if (HasAttribute(game,"debugging")) {
      if (game.debugging) {
        msg ("DEBUGGING: player.disabledskills = "+ player.disabledskills)
      }
    }
    player.staminacurrent = 1
    player.Stamina = player.staminacurrent + "/" + player.staminamax
    if (HasAttribute(game,"debugging")) {
      if (game.debugging) {
        msg ("DEBUGGING: player.Stamina = "+ player.Stamina)
      }
    }
    msg("Your stamina is now: "+player.Stamina)
  }
}
return (player.staminacurrent)

You are in an Entry 1099.
You can go south.

You take 5 points of stamina damage!

You have been knocked unconcious. You must choose a skill to disable.

DEBUGGING: player.Skills = Archery,Brawling

DEBUGGING: player.disabledskills = Agility

DEBUGGING: player.Stamina = 1/100

Your stamina is now: 1/100

You are in an Entry 2399.


show menu doesn't change the settings for some reason.

I'm researching that now.


I CAN TOO POST THIS HERE!!!


Hot diggity damn! I do prefer the other menu command, but I can certainly live with this option since it actually works. Thank you so very much! Didn't even know about that Join command. Sweet. :)


K.V.

You're welcome!


K.V.

That show menu works if it's not inside of that function, for some reason, which most assuredly involves script blocking.


If you make the show menu a function on its own, which is called from the first function, it works.

  <function name="modifystamina" parameters="modifier" type="int"><![CDATA[
    player.staminacurrent = player.staminacurrent + modifier
    if (player.staminacurrent > player.staminamax) {
      player.staminacurrent = player.staminamax
    }
    if (player.staminacurrent < 1 ) {
      if (ListCount (game.playerskills) = 1) {
        return (-99)
      }
      StaminaShowMenu
    }
    return (player.staminacurrent)
  ]]></function>
  <function name="StaminaShowMenu">
    msg ("You have been knocked unconcious. You must choose a skill to disable.")
    list = ListExclude(game.playerskills, "XxYyZzYy")
    show menu ("Pick a skill to disable:", list, false) {
      list remove (game.playerskills, result)
      list add (game.disabledskills, result)
      player.Skills = Join(game.playerskills,",")
      if (HasAttribute(game,"debugging")) {
        if (game.debugging) {
          msg ("DEBUGGING: player.Skills = "+player.Skills)
        }
      }
      player.disabledskills = Join(game.disabledskills,",")
      if (HasAttribute(game,"debugging")) {
        if (game.debugging) {
          msg ("DEBUGGING: player.disabledskills = "+ player.disabledskills)
        }
      }
      player.staminacurrent = 1
      player.Stamina = player.staminacurrent + "/" + player.staminamax
      if (HasAttribute(game,"debugging")) {
        if (game.debugging) {
          msg ("DEBUGGING: player.Stamina = "+ player.Stamina)
        }
      }
      msg ("Your stamina is now: "+player.Stamina)
    }
  </function>

It probably has something to do with that first function returning a value, but that's just a wild theory.


K.V.

Here is an example with a completely different approach.

I'm using a change script on player.staminacurrent to trigger the show menu.

The change script will make the modifystamina script happen, no matter what room the player is in.


NOTE: I removed the modifystamina function, putting the script in the aforementioned change script.

<!--Saved by Quest 5.7.6404.15496-->
<asl version="550">
  <include ref="English.aslx" />
  <include ref="Core.aslx" />
  <game name="Example Game 42">
    <gameid>b8e5fb45-e73d-47bb-8c07-27f2a20d1b20</gameid>
    <version>1.0</version>
    <firstpublished>2018</firstpublished>
    <start type="script"><![CDATA[
      game.debugging = true
      player.staminacurrent = 5
      // Set up a change script on player.staminacurrent:
      player.changedstaminacurrent => {
        if (player.staminacurrent > player.staminamax) {
          player.staminacurrent = player.staminamax
        }
        if (player.staminacurrent < 1 ) {
          if (ListCount (game.playerskills) = 1) {
            MoveObject (game.pov, Game Over)
          }
          else {
            msg ("You have been knocked unconcious. You must choose a skill to disable.")
            list = ListExclude(game.playerskills, "XxYyZzYy")
            show menu ("Pick a skill to disable:", list, false) {
              list remove (game.playerskills, result)
              list add (game.disabledskills, result)
              player.Skills = Join(game.playerskills,",")
              if (HasAttribute(game,"debugging")) {
                if (game.debugging) {
                  msg ("DEBUGGING: player.Skills = "+player.Skills)
                }
              }
              player.disabledskills = Join(game.disabledskills,",")
              if (HasAttribute(game,"debugging")) {
                if (game.debugging) {
                  msg ("DEBUGGING: player.disabledskills = "+ player.disabledskills)
                }
              }
              player.staminacurrent = 1
              player.Stamina = player.staminacurrent + "/" + player.staminamax
              if (HasAttribute(game,"debugging")) {
                if (game.debugging) {
                  msg ("DEBUGGING: player.Stamina = "+ player.Stamina)
                }
              }
              msg ("Your stamina is now: "+player.Stamina)
            }
          }
        }
      }
      player.staminamax = 100
      game.playerskills = Split("Archery;Agility;Brawling",";")
      game.disabledskills = NewStringList()
    ]]></start>
  </game>
  <object name="room">
    <inherit name="editor_room" />
    <enter type="script">
    </enter>
    <object name="player">
      <inherit name="editor_object" />
      <inherit name="editor_player" />
    </object>
    <exit alias="north" to="Entry 1099">
      <inherit name="northdirection" />
    </exit>
  </object>
  <object name="Entry 1099">
    <inherit name="editor_room" />
    <enter type="script"><![CDATA[
      msg ("You take 5 points of stamina damage!")
      player.staminacurrent = player.staminacurrent - 5
      on ready {
        if (player.staminacurrent>0) {
          MoveObject (player, Entry 2399)
        }
      }
    ]]></enter>
    <exit alias="south" to="room">
      <inherit name="southdirection" />
    </exit>
  </object>
  <object name="Entry 2399">
    <inherit name="editor_room" />
    <exit alias="south" to="room">
      <inherit name="southdirection" />
    </exit>
  </object>
  <object name="Game Over">
    <inherit name="editor_room" />
    <beforeenter type="script">
      finish
    </beforeenter>
    <descprefix type="string"></descprefix>
    <usedefaultprefix type="boolean">false</usedefaultprefix>
  </object>
</asl>

Kick ass! That works beautifully. Thank you!


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

Support

Forums