Convlib + phone

CheeseMyBaby
17 Apr 2018, 11:57

I'm using The Pixie's ConvLib and it's working really well.

I wonder how to "tie" it to a phone (object).
Ex:

(input) call 12345
when pressing enter I want the conversation to start without typing "talk to..." etc.
Is this doable?


jmnevil54
18 Apr 2018, 16:05

Couldn't you just change and copy the code for the talk command, into a new command? And then you could change the rest of the code if you needed to?


K.V.
18 Apr 2018, 18:02

Create a new game, open it in full code view, delete ALL the text, and paste this in.

Then, flip back to GUI to check out one way I would do it. (The phone is fixed in place in this example. I didn't add any components; no buttons, screen, rotary dial, receiver, speaker, mic... Nothing.)

<!--Saved by Quest 5.7.6606.27193-->
<asl version="550">
  <include ref="English.aslx" />
  <include ref="Core.aslx" />
  <game name="Call People">
    <gameid>8a58a8e3-51ad-4b3f-8afb-55aa9c16f281</gameid>
    <version>1.1</version>
    <firstpublished>2018</firstpublished>
    <feature_asktell />
  </game>
  <object name="room">
    <inherit name="editor_room" />
    <object name="player">
      <inherit name="editor_object" />
      <inherit name="editor_player" />
    </object>
    <object name="phone">
      <inherit name="editor_object" />
      <contacts type="stringdictionary">
        <item>
          <key>12345</key>
          <value>Ralph</value>
        </item>
      </contacts>
      <feature_usegive />
      <use type="script">
        msg ("You need to call a number. Try something like CALL 12345")
      </use>
      <hangup type="script">
        if (GetBoolean (game.pov, "onphone")) {
          msg ("You end the call.")
          DisconnectCall
        }
        else {
          msg ("You are not talking to anyone on the phone.")
        }
      </hangup>
      <look type="script"><![CDATA[
        msg ("An ordinary phone.  <br/><br/>To use it, call a number. Example: CALL 12345<br/><br/>To end a call, enter END CALL or HANG UP THE PHONE<br/>")
        if (ListCount(this.contacts)>0) {
          msg ("There is a list of contacts on it:<br/>")
          table = "<table class='contacts-table'><tr><th>Contact</th><th>Number</th></tr>"
          foreach (contact, this.contacts) {
            table = table + "<tr><td>"+this.contacts[contact]+"</td><td>"+contact+"</td></tr>"
          }
          table = table + "</table>"
          msg (table)
          JS.setCss (".contacts-table *", "padding:4px")
        }
      ]]></look>
      <takemsg>It's fixed in place.</takemsg>
      <displayverbs type="stringlist">
        <value>Look at</value>
        <value>Use</value>
      </displayverbs>
    </object>
    <exit alias="north" to="second room">
      <inherit name="northdirection" />
    </exit>
  </object>
  <object name="Ralph">
    <inherit name="editor_object" />
    <inherit name="namedmale" />
    <ask type="scriptdictionary">
      <item key="game">
        msg ("\"This is just an example game,\" says Ralph.")
      </item>
    </ask>
    <askdefault type="script">
      msg ("Ralph {random:says nothing:remains silent:does not reply}.")
    </askdefault>
    <telldefault type="script">
      msg ("Ralph {random:says nothing:remains silent:does not reply}.")
    </telldefault>
    <telltodefault type="script">
      msg ("Ralph {random:says nothing:remains silent:does not reply}.")
    </telltodefault>
    <speak type="script"><![CDATA[
      if (GetBoolean(Ralph,"onphone")) {
        msg ("\"You mean you called me just to talk?!?\"  Ralph sounds offended.  \"You're not even going to ask me about the game?!?\"<br/><br/>Click.  Ralph just hung up on you.")
        DisconnectCall
      }
      else {
        msg ("\"This game is boring,\" says Ralph.")
      }
    ]]></speak>
    <hellomsg>"Hello, this is Ralph."</hellomsg>
  </object>
  <command name="call_cmd">
    <pattern>call #text#;dial #text#</pattern>
    <script>
      if (not ListContains(ScopeReachable(),phone)) {
        msg ("You need a phone to do that.")
      }
      else {
        if (not GetBoolean(game.pov, "onphone")) {
          if (DictionaryContains(phone.contacts,Trim(text))) {
            o = StringDictionaryItem(phone.contacts,Trim(text))
            o = GetObject(o)
            if (not ListContains(ScopeReachable(),o)) {
              phone.aliasbak = GetDisplayAlias(phone)
              phone.alias = GetDisplayAlias(phone) + " (connected to "+GetDisplayName(o)+")"
              o.visiblebak = o.visible
              o.visible = true
              o.scenerybak = o.scenery
              o.scenery = true
              o.parent = o.parentbak
              MoveObjectHere (o)
              game.pov.onphone = true
              o.onphone = true
              phone.connectedto = o
              if (HasAttribute(o,"hellomsg")) {
                msg (o.hellomsg)
              }
              else {
                msg (CapFirst(GetDisplayName(o))+" answers the phone. \"Hello.\"")
              }
              EnableTurnScript (phone_surveillance)
            }
            else {
              msg (CapFirst(GetDisplayName(o))+" is here with you.  No need to call "+o.article+".")
            }
          }
          else {
            msg ("Your call did not go through.  Please check the number and try your call again.")
          }
        }
        else {
          msg ("You are currently on a call with " + GetDisplayName(phone.connectedto)+".")
        }
      }
    </script>
  </command>
  <command name="end_call_cmd">
    <pattern>end call;terminate call</pattern>
    <script>
      if (GetBoolean (game.pov, "onphone")) {
        msg ("You end the call.")
        DisconnectCall
      }
      else {
        msg ("You are not on the phone.")
      }
    </script>
  </command>
  <verb>
    <property>hangup</property>
    <pattern>hang up</pattern>
    <defaultexpression>"You can't hang up " + object.article + "."</defaultexpression>
  </verb>
  <turnscript name="phone_surveillance">
    <enabled type="boolean">false</enabled>
    <script><![CDATA[
      if (not ListContains(ScopeReachable(),phone)) {
        if (game.pov.onphone) {
          if (not GetBoolean(phone,"onhold")) {
            msg ("<br/>You have walked away from the phone, and "+GetDisplayName(phone.connectedto)+" probably hung up.<br/>")
            DisconnectCall
          }
        }
      }
    ]]></script>
  </turnscript>
  <object name="second room">
    <inherit name="editor_room" />
    <exit alias="south" to="room">
      <inherit name="southdirection" />
    </exit>
  </object>
  <function name="DisconnectCall">
    game.pov.onphone = false
	o = phone.connectedto
    o.onphone = false
    o.alias = o.aliasbak
    o.scenery = o.scenerybak
    o.visible = o.visiblebak
    o.parent = o.parentbak
    phone.alias = phone.aliasbak
    phone.connectedto = null
    DisableTurnScript (phone_surveillance)
  </function>
</asl>

K.V.
18 Apr 2018, 18:12

NOTE: I forgot about the bit with ConvLib.

Let me go check out what those functions are...


CheeseMyBaby
18 Apr 2018, 18:48

I have a switch with all available numbers. I want every number (well, some of them) to lead directly to a conversation.
I wrote this without checking your code above so maybe that's how you did it.

I'll copy/paste it straight away! =)


K.V.
18 Apr 2018, 20:24

I just added a 'contacts' dictionary to the phone. When you examine the phone, it prints the contacts as a table (if contacts exist.).


K.V.
18 Apr 2018, 20:27

This bit in my CALL command is where I make stuff happen as soon as you call someone:

              if (HasAttribute(o,"hellomsg")) {
                msg (o.hellomsg)
              }

hellomsg could be a script, too.

This change would allow you to use either a string or a script:

              if (HasAttribute(o,"hellomsg")) {
                if (HasString(o,"hellomsg")) msg (o.hellomsg)
                else if (HasScript(o,"hellomsg")) invoke(o.hellomsg)
              }

CheeseMyBaby
19 Apr 2018, 06:57

Tested it. It is very nice and if I'd used it from the start... that would've been rad :)
However; before starting to set up the actual phone I wrote lots and conversations. Lots and lots.
It would be swell if the possibility exist to hook up above coded phone to the convlib functions.


mrangel
19 Apr 2018, 08:20

Hmm...
I've not played with ConvLib much, but it looks pretty simple.

If you have NPC objects with a string attribute phonenumber

<command name="call">
  <pattern>call #text#</pattern>
  <script><![CDATA[
    person = FilterByAttribute (AllObjects(), "phonenumber", text)
    if (not player.parent = phone.parent) {
      // Yeah, there's better ways to do this if you have more than one phone object
      // but this is a simple example
      msg ("You'd need a phone to do that!")
    }
    else if (ListCount(person) > 0) {
      Converse (PickOneObject(person), "On the phone to "+text)
    }
    else {
      msg ("You dial "+text+", but nobody answers")
    }
  ]]></script>
</command>

K.V.
19 Apr 2018, 19:24

That works quite well, mrangel!


mrangel
20 Apr 2018, 09:38

Thanks :)
I was thinking about trying to preprocess numbers somehow; so it doesn't matter if the player types punctuation or spaces or whatever (just loop over the text parameter and remove all non-digit characters). Or allowing the player to have a phone book of numbers they already know.

Hmm... if game.phonebook is an objectlist, it might look something like this:

<command name="call">
  <pattern>^(?<text_verb>call|phone|ring|dial)\s*(?<text>(?:\W*\d)*\W*|(?<object>.+))$</pattern>
  <scope>game.phonebook</scope>
  <script><![CDATA[
    if (player.parent = phone.parent) {
      failmessage = "You dial "+text+", but nobody answers"
      if (IsDefined("object")) {
        if (object = phone) {
          // Need to account for player entering "dial phone" or similar, because the
          // phone itself is presumably in scope
          object = null
          failmessage = "You need to pick somebody to call. Try entering “"+text_verb+" Bob” or “"+text_verb+" 555-1234-999”"
        }
        else if (not ListContains(game.phonebook, object)) {
          // Thanks to alternate scope, player could have entered the name of someone in the room
          failmessage = "You don't have a phone number for "+GetDisplayName(object)
          object = null
        }
      }
      else {
        object = null
        number = ""
        for (i, 1, LengthOf(text)) {
          if (IsInt(Mid(text, i, 1))) {
            number = number + Mid(text, i, 1)
          }
        }
        if (number = "") {
          failmessage = "You need to pick somebody to call. Try entering “"+text_verb+" Bob” or “"+text_verb+" 555-1234-999”"
        }
        else if (LengthOf(number) = 1) {
          failmessage = "You pick up the phone and press the "+number+" button, but nothing happens"
        }
        else if (LengthOf(number) < 6) {
          failmessage = "You dial "+ToWords(LengthOf(number))+" digits, but the phone is waiting for more"
        }
        // not sure about other countries' phone systems
        // but here, if you dial extra digits at the end of a number it will still connect
        foreach (obj, AllObjects()) {
          if (HasString(obj, "phonenumber")) {
            if (StartsWith(obj.phonenumber, number)) {
              object = obj
            }
          }
        }
      }
      if (object = null) {
        msg (failmessage+".")
      else {
        Converse (object, "You call "+text)
      }
    }
    else {
      msg ("There isn't a phone here!")
    }
  ]]></script>
</command>

(off the top of my head, so probably an error or two)


K.V.
20 Apr 2018, 16:48

That looks pretty slick, too.

Currently, the call command is the one from the example.

Doing this makes that script work with ConvLib:

case (6700, "rick", "slick rick", "gucci crew ii") {
   Converse (Slick Rick, "Your call is now connected.  You can talk to ")
   // This is referencing the song Sally (That Girl) https://youtu.be/M8QcIoaisTg?t=120
} 


CheeseMyBaby
22 Apr 2018, 19:18

Thanks guys for all your input!
When I updated the convlib to the lastest version (thanks K.V. for pointing that out) I only need to change that line of code ((see example above) thanks K.V. for pointing that out) and now it's working exactly like I wanted it too (thanks K.V. for that)!

You guys are swell!


K.V.
22 Apr 2018, 21:55

Aw shucks... I didn't do nothin'....

Pixie and mrangel did all the real work.

Glad to hear it works now, though!


CheeseMyBaby
23 Apr 2018, 08:06

Sure they did! But you were the one who explained stuff to this incompetent noncoder!
There is such a thing as too much modesty man, take some credit! =)