Convlib + phone

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?


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.

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.

NOTE: I forgot about the bit with ConvLib.

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


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.

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.

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)
              }

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.


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.

That works quite well, mrangel!


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.

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
} 


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.

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

Pixie and mrangel did all the real work.

Glad to hear it works now, though!


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! =)


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

Support

Forums