Facebook Twitter YouTube Frictional Games | Forum | Privacy Policy | Dev Blog | Dev Wiki | Support | Gametee


Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
Need script help asap! extremely difficult script!
Apjjm Offline
Is easy to say

Posts: 496
Threads: 18
Joined: Apr 2011
Reputation: 52
#20
RE: Need script help asap! extremely difficult script!

TheGreatCthulhu provided a great method. I thought i would also offer some (rather late) input as to how you could approach the problem using strings in a more general case.

The code: http://pastebin.com/z48DpMQb
The code explained
Spoiler below!

Firstly, lets assume you can have any number of buttons - not just 0-9. but also letters and symbols too! To define all the symbols that are acceptable we shall use an array. In the following code we accept 0-9, A-F and the # symbol (you will need an area for each of these called ScriptArea_[Symbol]):
//Valid button characters (I.e. Characters for which an area exists)
string[] VALID_CHARS = {
    "0","1","2","3",
    "4","5","6","7",
    "8","9","A","B",
    "C","D","E","F",
    "#"};
Next, let's look at setting up the problem - which we will do inside a SetupButtons function/subroutine. Since we are making a password system of sorts - we need both target and current password variables. For now let's set the target password to "1234" - we can do more fancy stuff later. Additionally, we need to add callbacks for the Accept, Reject and symbol areas.
//Call this to setup the buttons
void SetupButtons()
{
    //Determine what the password should be
    SetLocalVarString("InputPassword","");
    SetLocalVarString("TargetPassword","1234");
    
    //Add an interact callback for each button
    for(uint i=0; i<VALID_CHARS.length(); i++)
    {
        //For each valid button character, get it's script area & add the use callback
        string area = "ScriptArea_" + VALID_CHARS[i];
        SetEntityPlayerInteractCallback(area,"cbButtonPress",false);
    }
    
    //Add callback for accept and cancel buttons
    SetEntityPlayerInteractCallback("ScriptArea_Accept","cbButtonEnter",false);
    SetEntityPlayerInteractCallback("ScriptArea_Cancel","cbButtonCancel",false);                    
}
In the code above "InputPassword" represents the password that has been input so far, and the "TargetPassword" is what the player has to type. Defining what to do when we enter a password or cancel the password is easy. For canceling we just clear the InputPassword, and to check correctness we can just check if the strings are equal:
//Callback for if the player has pressed the "enter"/"Accept" button.
void cbButtonEnter(string &in asButtonArea)
{
    //Is the target password the same as the input password?
    if(GetLocalVarString("TargetPassword") == GetLocalVarString("InputPassword"))
    {
        /* Todo: Your code for if the player has got the password correct! (E.g Unlock/Open door) */
        
        //De-activate all the buttons
        for(uint i=0; i<VALID_CHARS.length(); i++) SetEntityActive("ScriptArea_" + VALID_CHARS[i],false);
        SetEntityActive("ScriptArea_Accept",false);
        SetEntityActive("ScriptArea_Cancel",false);
    }
    else
    {
        /* Todo: Some code for if the player got the password wrong! */
    }
    
    //Reset the input password
    SetLocalVarString("InputPassword","");
}

//Callback for if the player has pressed the "cancel" button
void cbButtonCancel(string &in asButtonArea)
{
    SetLocalVarString("InputPassword","");
}
In the code above you can see i've been a little fancy by deactivating the input areas if the password is correct and enter is pressed. Next up is the tricky part - we need to get the symbol out of the script area's name. Thankfully, i've already written a function to do this kind of thing called "StringSplit". For example splitting a string using "_" on "ScriptArea_1" would return "ScriptArea" and "1" in an array. You don't really need to understand how this code works if you don't want to:
//Helper Function: This will split a string using a specified delimiter.
//E.g. StringSplit("Hello_World","_");
//     returns an array containing "Hello" and "World"
string[] stringSplit(string asString, string asDelim)
{
  string[] output = {""};
  //For each character in the input, check against the output.
  int s1 = int(asString.length()); int s2 = int(asDelim.length());
  int lastMatch = 0;
  //Add all but final elements
  for(int i=0; i<=s1 - s2; i++)
   {
    if(StringSub(asString,i,s2) == asDelim)
     {
      //Add element to output      
      output[output.length() - 1] = StringSub(asString,lastMatch,i-lastMatch);
      output.resize(output.length() + 1);
      //Move search along
      i += s2;
      lastMatch = i;
     }
   }
  //Add lastMatch -> final
  output[output.length() - 1] = StringSub(asString,lastMatch,s1 - lastMatch);
  return output;
}
So, we can get the character by looking at the second element (index 1) of the array returned by the splitting routine! The next thing to check is that the player hasn't entered in a password that is too long (we would probably want to reject the password straight away in this case!). Getting the length of the input and target password isn't too hard and is fairly obvious in the code below, which handles any symbol button being pressed:
//Callback triggered when a button is pressed
void cbButtonPress(string &in asButtonArea)
{
    /* TODO HERE: Any sounds or effects for pressing the button! */
    
    //Split the button area using _ so you have "ScriptArea" and "<ID>"
    string[] buttonSplit = stringSplit(asButtonArea,"_");
    //Button name is fine so get the Button character (Second array element if ScriptArea_<ID>)
    string buttonchar = buttonSplit[1];
    
    //Get the max password length (This is just the length of the target password);
    uint maxPasswordLength = GetLocalVarString("TargetPassword").length();
    //Determine the length of the new password
    uint newPasswordLength = GetLocalVarString("InputPassword").length() + buttonchar.length();
    
    //Accept the button press if the new password is valid
    if(newPasswordLength <= maxPasswordLength)
     {
        //Player has entered password was fine in length, add this character to the password.
        AddLocalVarString("InputPassword",buttonchar);
     }
    else
     {
        //Player has entered a password that was too long - clear the password and enter (reject)
        SetLocalVarString("InputPassword","");
        cbButtonEnter("");
     }
}

Bonus bit: Generating random passwords of any length!
This can be done by continually picking random characters from our "VALID_CHARS" array until a password of suitable length is created:
//Returns a random password of a given length
string GetRandomPassword(uint passwordLength)
{
    //Password to be generated
    string password = "";
    
    //Calculate the maximum integer to be randomly selected. Error if there are no chars to choose from!
    int maxChar = int(VALID_CHARS.length())-1;
    if(maxChar < 0) { AddDebugMessage("No VALID_CHARS specified!",false); return "";}
    
    //Generate a password until it satisfies the length criteria and then return it.
    while(password.length() < passwordLength)
    {
        password += VALID_CHARS[RandInt(0,maxChar)];
    }
    
    return password;
}
We can then update the first part of the setup buttons routine as follows, getting the code availible on pastebin:
    //Determine what the password should be at random
    SetLocalVarString("InputPassword","");
    SetLocalVarString("TargetPassword",GetRandomPassword(4));


Note that if you want to get the "TargetPassword" for displaying it (this is a little bit tricky but i can write up how to do this if you would like) you can use GetLocalVarString("TargetPassword").

12-20-2012, 07:31 PM
Find


Messages In This Thread
RE: Need script help asap! extremely difficult script! - by Apjjm - 12-20-2012, 07:31 PM



Users browsing this thread: 1 Guest(s)