LiftLib5.4 problem

baskham
14 Feb 2018, 20:00

Hi.

I have been playing around with LiftLib5.4 a bit.
It looks like a very neat way to handle elevators.

But I have a couple of issues.

  1. If the map is enabled, a load of errormsgs will occur when exiting the lift.
    Like this:
    "Error running script: Error evaluating expression 'DictionaryItem(coordinates, coordinate)': The given key was not present in the dictionary."
    I am guessing this is because Quest can't handle being dropped in a new location.
    But is there a way around this, or will I just have to go without the map?

  2. When the lift has moved to a new location it just displays the arrival message.
    Is there a way to print the room description for the liftroom incl the hyperlink to the exit?

  3. I can't figure out how to translate the Press command for a liftbutton.
    i have tried adding it to the verb template in the lib. And I have tried adding the proper word (tryk) to the displayverb list.
    But no success.
    And as a sidenote, it would be great if clicking the link for the button would just activate it instead of presenting a -item menu.
    But I guess that is to much to ask :-D

Anyway.
I am having a ball playing with Quest.
Thank you so much for keeping it alive.

BR
Benny.


The Pixie
15 Feb 2018, 08:43

I have just updated LiftLib, and the instructions, so some of this will be easier. The instructions have also moved, and are now here:
https://github.com/ThePix/quest/wiki/Library:-Lifts

  1. The map has problems when we try to do stuff that is a little odd. Take a look at the Teleporting section of the tutorial; one of the solutions there may be suitable and may work. I have never used the map with LiftLib, so it may take some trial and error I am afraid.
    http://docs.textadventures.co.uk/quest/showing_a_map.html

  2. You can now override the Arrival function to do this; see the instructions.

  3. The updated instructions now explains how to do this.

You could set the buttons to be scenery, which would stop Quest putting them in the room descriptions (they would also not appear in the inventory pane). Then you could have the buttons in the room description you write, with a command link.

You can see two buttons, one marked {command:press first floor button:first floor}, the other {command:press second floor button:second floor}


mrangel
15 Feb 2018, 10:57

I'm thinking that when the current floor changes, you could add the change in floor numbers onto the room's z coordinate; then call Grid_CalculateMapCoordinates and Grid_Redraw (which I think should be efficient to make it calculate the coordinates for the room outside the lift on the destination floor).
Possibly checking if the room outside already has coordinates, and if so change the lift's coordinates to be adjacent to that room; but that would be a bit more code.


baskham
15 Feb 2018, 18:43

Thank you for the new version.
I am impressed with the speed of updates here :-)

But.
There seems to be a problem.
I have implemented a lift.
I have not done anything with translations or descriptions.
Just added a lift, exits and buttons as described.

But when i stand in the elevator and press a button, i get the msg:
"Error running script: Error compiling expression 'notmoved': Unknown object or variable 'notmoved'"

If I then walk out of the elevator I get:
"Error running script: Error compiling expression 'not this.leavingmsg = ""': Unknown object or variable 'this'"
But the elevator has actually moved.
I get the correct room description for the new floor.

BR Benny


K.V.
15 Feb 2018, 20:13

At the very end of the PressButton() function:

Change:

      if (not silently) {
        Arrival(button, s, notmoved)
      }

To:

      if (not silently) {
        Arrival(button, s, moved)
      }

Then...

In the library (or in full code view), replace LeavingTheLift() with this (or just add the parameter "this"):

  <function name="LeavingTheLift" parameters="this">
    if (not this.leavingmsg = "") {
      msg (this.leavingmsg)
    }
	</function>

Finally, change the onexit script on the "liftroom" type to this:

 <type name="liftroom">
    <current_floor type="int">1</current_floor>
    <usage_count type="int">0</usage_count>
    <lockexits type="boolean">false</lockexits>
    <goingup>The lift ascends to ###.</goingup>
    <goingdown>The lift descends to ###.</goingdown>
    <leavingmsg type="string"></leavingmsg>
    <samefloor>Nothing happens. Perhaps because you are already on ###.</samefloor>
    <onexit type="script">
      LeavingTheLift(this)
    </onexit>
  </type>

K.V.
15 Feb 2018, 21:05

Going by MrAngel's suggestion and the "showing a map" guide, I ended up with a script which I think would work if the lift actually moved.

The way it is now, you can remove all the grid functions, and everything works the same.

I have a different image set for each room on a different level.

When you move up or down in the lift, the map doesn't change until you exit the lift. At that point, the images behave correctly with or without adding the bits including Grid_SetGridCoordinateForPlayer.

  <function name="_PressButton" parameters="button, silently">
      exit = ObjectListItem (ScopeExitsForRoom (button.parent), 0)
      current = exit.to
      current_button = null
      foreach (o, GetDirectChildren(button.parent)) {
        if (o.destination = current) current_button = o
      }
      if (exit.to = button.destination) {
        moved = false
        s = button.parent.samefloor
      }
      else {
        moved = true
		lastFloor = current.name
		lastFloor = GetObject(lastFloor)
        exit.to = button.destination
        if (button.parent.current_floor > button.floor) {
		  if (game.gridmap) {
			Grid_SetGridCoordinateForPlayer (game.pov, lastFloor, "z", Grid_GetGridCoordinateForPlayer(game.pov, exit.to, "z")+1)
	      }
          s = button.parent.goingdown
        }
        else {
		  if (game.gridmap) {
		    Grid_SetGridCoordinateForPlayer (game.pov, exit.to, "z", Grid_GetGridCoordinateForPlayer(game.pov, lastFloor, "z")+1)
	      }
          s = button.parent.goingup
        }
        button.parent.current_floor = button.floor
        if (not current_button = null) {
          if (HasString(current_button, "departure")) {
            s = current_button.departure + " " + s
          }
        }
        if (HasString(button, "arrival")) {
          s = s + " " + button.arrival
        }
        button.parent.usage_count = button.parent.usage_count + 1
      }
      // prepend the button pressing message
      s = button.pressmsg + " " + s
      // Swap ### for the floor name
      if (HasString(button, "floorname")) {
        s = Replace (s, "###", ToString (button.floorname))
      }
      else {
        s = Replace (s, "###", "floor " + button.floor)
      }
      if (not silently) {
        Arrival(button, s, moved)
      }
	</function>

Adding Grid_Redraw() didn't make any difference, either.


Where is the "z" coordinate coming from?

I've been poring over the grid functions, but I can't find the origin of "z".


mrangel
15 Feb 2018, 23:12

Where is the "z" coordinate coming from?
I've been poring over the grid functions, but I can't find the origin of "z".

Looks like it's increased/decreased by Grid_CalculateMapCoordinates when it sees an exit that inherits the up/down directions.

I was thinking of something like ...

Grid_SetGridCoordinateForPlayer (game.pov, button.parent, "z", Grid_GetGridCoordinateForPlayer(game.pov, button.parent, "z") + button.floor - button.parent.current_floor)

Grid_CalculateMapCoordinates (button.parent, game.pov)

Grid_Redraw()

Changes the z coordinate of the lift itself, so it's drawn on the floor you last got out of it on.

(Though if I was building a library like this, I'd likely have the buttons display a message and change current_floor, and give the lift room a changedcurrent_floor script that handles moving the exits. More cleanly separating the button logic (which a user might want to change; such as having lockable buttons) from the exit-and-grid-moving logic (which are unlikely to need changing))


Anonynn
16 Feb 2018, 04:03

I'm confused why this is even a library? Can't you just make a bunch of up rooms and lock them, and then at the lock ask what floor the player would like to go to, correspond those floors with the rooms and then add some description that says something like..."you pass rooms 43, 44, 45, 46, 47, 48 and arrive at floor 49 and vice versa for going to any of the other rooms. Just curious is all :) Unless it was an exercise for coding or something.

Anonynn.


K.V.
16 Feb 2018, 04:24

I couldn't get the grid to behave correctly with that library (which is due to my lack of knowledge concerning the grid), so I made this one (which is inferior (and is an exercise for coding or something), but seems to work (tested offline only)):

ElevatorLib.aslx
https://gist.github.com/KVonGit/44e6fc640237dedcbed361146ceaabfd

ElevatorLibTester.aslx
https://gist.github.com/KVonGit/b0d72e81d9c82c38aad7056a93189c05

Test it out online (seems to work online or offline):
http://textadventures.co.uk/games/view/ztjksxjmbeugnybfaqkgxa/elevatorlibtester


This works with GridImageLib, too:

https://gist.github.com/KVonGit/2851a12ee553599d8e7ee80939227ed5#file-gridimagelib-aslx


I just now saw mrangel's last post.

I'll try that out on LiftLib and return.


UPDATE

I added mrangel's code to LiftLib, and it works on the way up, but using the lift after reaching the top messed all the layers up. (I'm quite certain I didn't put the code in the right place.)

      else {
        moved = true
		lastFloor = current.name
		lastFloor = GetObject(lastFloor)
        exit.to = button.destination
        if (button.parent.current_floor > button.floor) {
		  if (game.gridmap) {
			Grid_SetGridCoordinateForPlayer (game.pov, button.parent, "z", Grid_GetGridCoordinateForPlayer(game.pov, button.parent, "z") + button.floor - button.parent.current_floor)

			Grid_CalculateMapCoordinates (button.parent, game.pov)

			Grid_Redraw()
	      }
          s = button.parent.goingdown
        }
        else {
		  if (game.gridmap) {
		    Grid_SetGridCoordinateForPlayer (game.pov, button.parent, "z", Grid_GetGridCoordinateForPlayer(game.pov, button.parent, "z") + button.floor - button.parent.current_floor)

			Grid_CalculateMapCoordinates (button.parent, game.pov)

			Grid_Redraw()
	      }
          s = button.parent.goingup
        }

mrangel
16 Feb 2018, 10:07

I added mrangel's code to LiftLib, and it works on the way up, but using the lift after reaching the top messed all the layers up. (I'm quite certain I didn't put the code in the right place.)

I'm assuming the code can be placed after changing exit.to but before changing current_floor. Looks right.
By "messes up the layers", do you mean that it redraws the lift room on the layer it's now on, but leaves the player 'dot' on the wrong floor?
The player's moved to a different floor, but their changedparentscript hasn't been called.

Might be easier to do this by giving the liftroom a changedcurrent_floor so that it fires correctly whether triggered by a button, some other script, or when the player enters the lift:

  if (game.gridmap) {
    if (Grid_GetRoomBooleanForPlayer(game.pov, object, "grid_isdrawn")) {
      Grid_SetGridCoordinateForPlayer (game.pov, this, "z", Grid_GetGridCoordinateForPlayer(game.pov, this, "z") + this.current_floor - oldvalue)
      Grid_CalculateMapCoordinates (button.parent, game.pov)
      Grid_Redraw()
      if (this = game.pov.parent) {
        Grid_DrawPlayerInRoom (this)
      }
    }
  }

Does that play any better?

(Actually... sorry for the tangent from the original thread... but I think it might be more elegant to model a lift as a series of rooms, one for each floor, connected by invisible up/down exits, and a "lift controller" object that might be invisible. The lift controller's changedparent script unlocks the doors on the floor it's on, locks the doors on all other floors, and moves all objects inside the lift to the same room as it. The lift buttons (and call buttons) loop over moving the lift controller to the specified floor, one floor at a time. If you're working with some kind of timing system, you could even have a turnscript that moves the lift controller up to a certain number of floors towards the chosen one. Press the call button and the lift moves towards your current location at 3 floors per turn, giving the guys chasing you a chance to catch up. And because you're moving one floor at a time, it will call the player's changedparent once for every floor - and the map script checks for an exit between your old and new rooms, even if it's invisible)


K.V.
16 Feb 2018, 14:25

By "messes up the layers", do you mean that it redraws the lift room on the layer it's now on, but leaves the player 'dot' on the wrong floor?

It kept on adding more and more layers once you reached the upper-most level. (It was doing other weird things, too. In my experience, once the map goes crazy, it does not get back in line until you restart.)

Might be easier to do this by giving the liftroom a changedcurrent_floor

That's a good idea. I'll test it out. (I'd like to make Pixie's library work with the map, if possible.)

Actually... sorry for the tangent from the original thread... but I think it might be more elegant to model a lift as a series of rooms, one for each floor, connected by invisible up/down exits

Ha! That's funny. That's what I ended up making yesterday.

(I made myself a note to add the elevator doors. I was debating how the turns between floors should work, and decided to leave all that alone until today.)

http://textadventures.co.uk/forum/quest/topic/a393qorxxeyokj46x8sdzq/liftlib5-4-problem#bfd52e1d-addf-407a-afd8-9f33a327e4ab


K.V.
16 Feb 2018, 16:27

This is what I've got going now:

OLD CODE
<attr name="changedcurrent_floor" type="script">
      thisdict = DictionaryItem(player.grid_coordinates,"lift")
      thisZ = DictionaryItem(thisdict,"z")
      // msg(thisZ)
      oldvalue = this.last_floor
      currentvalue = this.current_floor
      change = oldvalue - currentvalue
      if (game.gridmap) {
        if (Grid_GetRoomBooleanForPlayer(game.pov, this, "grid_isdrawn")) {
          newZ = thisZ + change
          dictionary remove (thisdict, "z")
          dictionary add (thisdict, "z", currentvalue*1.0-1)
          // Grid_CalculateMapCoordinates (this, game.pov) //THIS EFFECTS NOTHING
          // Grid_Redraw  //THIS CLEARS ANY GRID FILLS
          Grid_DrawPlayerInRoom (game.pov.parent)
          //VisitRoom (game.pov.parent)  //THIS EFFECTS NOTHING
        }
      }
    </attr>

It does everything EXCEPT make the lift appear to be on the same level as the player. Meaning the grid is just faded out, but everything else looks and works correctly.

image


baskham
19 Feb 2018, 13:55

Hi guys.

I have now tried the solution for the LiftLib.
It works like a breeze :-)
Thank you!!

I will try out the mapping part later today or tomorrow.

BR Benny.


baskham
21 Feb 2018, 17:45

Hmm.

Maybe I am overestimating my on skills....

But from all the updates in this thread, I can't really figure out what to change where to get the map working :-(


K.V.
21 Feb 2018, 18:33

This is the best I've come up with when using the library you are using.

Well... The library on GitHub is LiftLib v2.1, and this is that, only slightly modified. (Thanks to mrangel!)


The library (modified):

Current mod of LiftLib.aslx


The example game:

<!--Saved by Quest 5.7.6606.27193-->
<asl version="550">
  <include ref="English.aslx" />
  <include ref="Core.aslx" />
  <include ref="LiftLib.aslx" />
  <game name="Lift Test">
    <gameid>7c83176c-78e9-47e5-a841-120cf10fa971</gameid>
    <version>1.0</version>
    <firstpublished>2018</firstpublished>
    <gridmap />
  </game>
  <object name="room">
    <inherit name="editor_room" />
  </object>
  <object name="first floor lobby">
    <inherit name="editor_room" />
    <inherit name="liftentrance" />
    <exit name="EXIT_f1_to_lift" alias="north" to="lift">
      <inherit name="liftentrance" />
      <inherit name="northdirection" />
    </exit>
    <exit name="EXIT_f1_to_f2" alias="up the stairs" to="second floor lobby">
      <inherit name="updirection" />
      <runscript />
      <script type="script">
        MapUpFrom(this.to)
        game.pov.parent = this.to
      </script>
    </exit>
    <object name="player">
      <inherit name="editor_object" />
      <inherit name="editor_player" />
      <changedparent type="script">
        if (game.pov = this) {
          if (IsDefined("oldvalue")) {
            OnEnterRoom (oldvalue)
            this.lastparent = oldvalue
          }
          else {
            OnEnterRoom (null)
          }
          if (game.gridmap) {
            MergePOVCoordinates
          }
        }
        this.hasbeenmoved = true
      </changedparent>
    </object>
  </object>
  <object name="second floor lobby">
    <inherit name="editor_room" />
    <exit name="EXIT_f2_to_lift" alias="north" to="lift">
      <inherit name="liftentrance" />
      <inherit name="northdirection" />
    </exit>
    <exit name="EXIT_f2_to_f1" alias="down the stairs" to="first floor lobby">
      <inherit name="downdirection" />
      <runscript />
      <script type="script">
        MapDownFrom(this.to)
        game.pov.parent = this.to
      </script>
    </exit>
    <exit name="EXIT_f2_to_f3" alias="up the stairs" to="third floor lobby">
      <inherit name="updirection" />
      <runscript />
      <script type="script">
        MapUpFrom(this.to)
        game.pov.parent = this.to
      </script>
    </exit>
    <exit name="EXIT_f2_to_offices" alias="west" to="offices">
      <inherit name="westdirection" />
    </exit>
  </object>
  <object name="third floor lobby">
    <inherit name="editor_room" />
    <exit name="EXIT_f3_to_lift" alias="north" to="lift">
      <inherit name="liftentrance" />
      <inherit name="northdirection" />
    </exit>
    <exit name="EXIT_f3_to_f2" alias="down the stairs" to="second floor lobby">
      <inherit name="downdirection" />
      <runscript />
      <script type="script">
        MapDownFrom(this.to)
        game.pov.parent = this.to
      </script>
    </exit>
    <exit name="EXIT_f3_to_meetingrooms" alias="east" to="meeting rooms">
      <inherit name="eastdirection" />
    </exit>
  </object>
  <object name="lift">
    <inherit name="editor_room" />
    <inherit name="liftroom" />
    <attr name="grid_fill">Navy</attr>
    <exit name="EXIT_lift_to_f1" alias="south" to="first floor lobby">
      <inherit name="southdirection" />
    </exit>
    <object name="button1">
      <inherit name="editor_object" />
      <inherit name="liftbutton" />
      <alias>button marked "1"</alias>
      <alt type="stringlist">
        <value>button 1</value>
      </alt>
      <destination type="object">first floor lobby</destination>
    </object>
    <object name="button2">
      <inherit name="editor_object" />
      <inherit name="liftbutton" />
      <floor type="int">2</floor>
      <alias>button marked "2"</alias>
      <alt type="stringlist">
        <value>button 2</value>
      </alt>
      <destination type="object">second floor lobby</destination>
    </object>
    <object name="button3">
      <inherit name="editor_object" />
      <inherit name="liftbutton" />
      <floor type="int">3</floor>
      <alias>button marked "3"</alias>
      <alt type="stringlist">
        <value>button 3</value>
      </alt>
      <destination type="object">third floor lobby</destination>
    </object>
  </object>
  <object name="offices">
    <inherit name="editor_room" />
    <exit alias="east" to="second floor lobby">
      <inherit name="eastdirection" />
    </exit>
  </object>
  <object name="meeting rooms">
    <inherit name="editor_room" />
    <exit alias="west" to="third floor lobby">
      <inherit name="westdirection" />
    </exit>
  </object>
  <function name="MapUpFrom" parameters="room">
    Grid_SetGridCoordinateForPlayer (game.pov, room, "z", Grid_GetGridCoordinateForPlayer(game.pov, game.pov.parent, "z")+1)
  </function>
  <function name="MapDownFrom" parameters="room">
    Grid_SetGridCoordinateForPlayer (game.pov, game.pov.parent, "z", Grid_GetGridCoordinateForPlayer(game.pov, room, "z")+1)
  </function>
</asl>

baskham
23 Feb 2018, 20:25

Yay!!!

It works like a charm.
Thank you so much!!

Only one little thing.
if you disable the map in the game object, it complains when you press a liftbutton:
"'DictionaryItem(player.grid_coordinates,"Elevator1")': DictionaryItem function expected dictionary parameter but was passed 'null'"

Elevator1 is the name of my liftroom.

BR Benny


mrangel
23 Feb 2018, 20:42

@KV
Not sure why you have this line in the changed_currentfloor function:

oldvalue = this.last_floor

Seems like it might be adding a possibility for future odd behaviour. Within a script named changedcurrent_floor, you already have a special variable named oldvalue that contains the previous value of this.current_floor. This is behaviour of changed* functions.


K.V.
23 Feb 2018, 20:46

Whoops!

I made an error in the liftroom type's script.


The revised, modified library:

Current mod of LiftLib.aslx


K.V.
23 Feb 2018, 20:48

Within a script named changedcurrent_floor, you already have a special variable named oldvalue that contains the previous value of this.current_floor.

I thought so, too, but just using oldvalue in the script threw an error. So, I added that line. (It is highly probable that I had it messed up somehow, though.)


Just double checked.

When I comment that line out, I get this error:

Error running script: Error compiling expression 'oldvalue - currentvalue': ArithmeticElement: Operation 'Subtract' is not defined for types 'Object' and 'Int32'
You press the button. The lift ascends to floor 2.


mrangel
23 Feb 2018, 21:08

That's weird.
Oh; oldvalue is null the first time you assign something to it. (Even if it previously had a value inherited from its type, I think? Because the variable of the object itself is being set now)

However, your use of last_floor is problematic, because before setting the current floor, you've done:

button.parent.last_floor = button.floor

So you're setting both currentvalue and oldvalue to the floor property of the button that's been pressed. I think you either want current_button.floor in that line; or you want to set last_floor after changing current_floor so that it will have the right value next time.


K.V.
23 Feb 2018, 22:39

Thank you!

I didn't even notice that.

(I fixed it in the last post.)


baskham
25 Feb 2018, 18:26

Hmmm.

This is a little weird.

With the library from feb. 21. It works with the map enabled but not when it is disabled.

With the new lib from feb. 23. It is the other way around.
Now when the map is enabled I get:
"Error running script: Error evaluating expression 'DictionaryItem(player.grid_coordinates,"lift")': The given key was not present in the dictionary."
(Note it now says "lift" in the errormsg. My lift is called "elevator1")
And when I disable the map it works :-O :'(

BR
Benny


K.V.
26 Feb 2018, 04:17

Make a backup copy of your copy of LiftLib.

Open the LiftLib file in your game's folder in a text editor.

Delete ALL the text.

Paste this in and save. (This is the same code posted here.)

Run the game.

(This works with or without the map for me.)

Current mod of LiftLib.aslx


baskham
26 Feb 2018, 17:47

I tried the last version of the liftlib.
Both with my project and with a VERY simple little game.

I still got the same problem.
But I managed to figure out why!!!!

The lift must be called lift.
Otherwise it complains when the map is enabled.

I can definitely live with that.
At least for now :-)
But it might be worth fixing.

BR Benny


K.V.
26 Feb 2018, 18:10

Mine is called "Elevator" in this game, and it works perfectly using the library in this post.


The example game:

<!--Saved by Quest 5.7.6606.27193-->
<asl version="550">
  <include ref="English.aslx" />
  <include ref="Core.aslx" />
  <include ref="LiftLib.aslx" />
  <game name="Lift Test">
    <gameid>7c83176c-78e9-47e5-a841-120cf10fa971</gameid>
    <version>1.0</version>
    <firstpublished>2018</firstpublished>
    <gridmap type="boolean">false</gridmap>
  </game>
  <object name="room">
    <inherit name="editor_room" />
  </object>
  <object name="first floor lobby">
    <inherit name="editor_room" />
    <inherit name="liftentrance" />
    <exit name="EXIT_f1_to_lift" alias="north" to="Elevator">
      <inherit name="liftentrance" />
      <inherit name="northdirection" />
    </exit>
    <exit name="EXIT_f1_to_f2" alias="up the stairs" to="second floor lobby">
      <inherit name="updirection" />
      <runscript />
      <script type="script">
        MapUpFrom (this.to)
        game.pov.parent = this.to
      </script>
    </exit>
    <object name="player">
      <inherit name="editor_object" />
      <inherit name="editor_player" />
      <changedparent type="script">
        if (game.pov = this) {
          if (IsDefined("oldvalue")) {
            OnEnterRoom (oldvalue)
            this.lastparent = oldvalue
          }
          else {
            OnEnterRoom (null)
          }
          if (game.gridmap) {
            MergePOVCoordinates
          }
        }
        this.hasbeenmoved = true
      </changedparent>
    </object>
  </object>
  <object name="second floor lobby">
    <inherit name="editor_room" />
    <exit name="EXIT_f2_to_lift" alias="north" to="Elevator">
      <inherit name="liftentrance" />
      <inherit name="northdirection" />
    </exit>
    <exit name="EXIT_f2_to_f1" alias="down the stairs" to="first floor lobby">
      <inherit name="downdirection" />
      <runscript />
      <script type="script">
        MapDownFrom (this.to)
        game.pov.parent = this.to
      </script>
    </exit>
    <exit name="EXIT_f2_to_f3" alias="up the stairs" to="third floor lobby">
      <inherit name="updirection" />
      <runscript />
      <script type="script">
        MapUpFrom (this.to)
        game.pov.parent = this.to
      </script>
    </exit>
    <exit name="EXIT_f2_to_offices" alias="west" to="offices">
      <inherit name="westdirection" />
    </exit>
  </object>
  <object name="third floor lobby">
    <inherit name="editor_room" />
    <exit name="EXIT_f3_to_lift" alias="north" to="Elevator">
      <inherit name="liftentrance" />
      <inherit name="northdirection" />
    </exit>
    <exit name="EXIT_f3_to_f2" alias="down the stairs" to="second floor lobby">
      <inherit name="downdirection" />
      <runscript />
      <script type="script">
        MapDownFrom (this.to)
        game.pov.parent = this.to
      </script>
    </exit>
    <exit name="EXIT_f3_to_meetingrooms" alias="east" to="meeting rooms">
      <inherit name="eastdirection" />
    </exit>
  </object>
  <object name="Elevator">
    <inherit name="editor_room" />
    <inherit name="liftroom" />
    <attr name="grid_fill">Navy</attr>
    <exit name="EXIT_lift_to_f1" alias="south" to="first floor lobby">
      <inherit name="southdirection" />
    </exit>
    <object name="button1">
      <inherit name="editor_object" />
      <inherit name="liftbutton" />
      <alias>button marked "1"</alias>
      <alt type="stringlist">
        <value>button 1</value>
      </alt>
      <destination type="object">first floor lobby</destination>
    </object>
    <object name="button2">
      <inherit name="editor_object" />
      <inherit name="liftbutton" />
      <floor type="int">2</floor>
      <alias>button marked "2"</alias>
      <alt type="stringlist">
        <value>button 2</value>
      </alt>
      <destination type="object">second floor lobby</destination>
    </object>
    <object name="button3">
      <inherit name="editor_object" />
      <inherit name="liftbutton" />
      <floor type="int">3</floor>
      <alias>button marked "3"</alias>
      <alt type="stringlist">
        <value>button 3</value>
      </alt>
      <destination type="object">third floor lobby</destination>
    </object>
  </object>
  <object name="offices">
    <inherit name="editor_room" />
    <exit alias="east" to="second floor lobby">
      <inherit name="eastdirection" />
    </exit>
  </object>
  <object name="meeting rooms">
    <inherit name="editor_room" />
    <exit alias="west" to="third floor lobby">
      <inherit name="westdirection" />
    </exit>
  </object>
  <function name="MapUpFrom" parameters="room">
    Grid_SetGridCoordinateForPlayer (game.pov, room, "z", Grid_GetGridCoordinateForPlayer(game.pov, game.pov.parent, "z")+1)
  </function>
  <function name="MapDownFrom" parameters="room">
    Grid_SetGridCoordinateForPlayer (game.pov, game.pov.parent, "z", Grid_GetGridCoordinateForPlayer(game.pov, room, "z")+1)
  </function>
</asl>

Are you setting the lift object up with the "lifttype" type?


baskham
26 Feb 2018, 18:34

This is so weird!!

I use the lib you posted yesterday.
And the game below.

And it complains if the map is enabled and the lift is called anything other than "lift"
Otherwise it is fine. :-O:-O`


<asl version="550">
  <include ref="English.aslx" />
  <include ref="Core.aslx" />
  <include ref="LiftLib.aslx" />
  <game name="lifttesta">
    <gameid>22bf84c4-8e87-42d3-9884-89491618f4b9</gameid>
    <version>1.0</version>
    <firstpublished>2018</firstpublished>
    <gridmap />
  </game>
  <object name="room">
    <inherit name="editor_room" />
    <object name="player">
      <inherit name="editor_object" />
      <inherit name="editor_player" />
    </object>
    <exit alias="east" to="room1">
      <inherit name="eastdirection" />
    </exit>
    <object name="hammer">
      <inherit name="editor_object" />
      <take />
      <feature_usegive />
      <selfuseon type="scriptdictionary" />
    </object>
    <object name="nail">
      <inherit name="editor_object" />
      <feature_usegive />
      <useon type="scriptdictionary">
        <item key="hammer">
          msg ("bang bang")
        </item>
      </useon>
    </object>
  </object>
  <object name="room1">
    <inherit name="editor_room" />
    <exit alias="west" to="room">
      <inherit name="westdirection" />
    </exit>
    <exit alias="east" to="room2">
      <inherit name="eastdirection" />
    </exit>
  </object>
  <object name="room2">
    <inherit name="editor_room" />
    <exit alias="west" to="room1">
      <inherit name="westdirection" />
    </exit>
    <exit alias="east" to="lift">
      <inherit name="eastdirection" />
      <inherit name="liftentrance" />
    </exit>
  </object>
  <object name="lift">
    <inherit name="editor_room" />
    <inherit name="liftroom" />
    <object name="knap1">
      <inherit name="editor_object" />
      <inherit name="liftbutton" />
      <floor type="int">1</floor>
      <destination type="object">room2</destination>
    </object>
    <object name="knap2">
      <inherit name="editor_object" />
      <inherit name="liftbutton" />
      <floor type="int">2</floor>
      <destination type="object">rooma</destination>
    </object>
    <exit alias="west" to="room2">
      <inherit name="westdirection" />
    </exit>
  </object>
  <object name="rooma">
    <inherit name="editor_room" />
    <exit alias="south" to="roomb">
      <inherit name="southdirection" />
    </exit>
    <exit alias="east" to="lift">
      <inherit name="eastdirection" />
      <inherit name="liftentrance" />
    </exit>
  </object>
  <object name="roomb">
    <inherit name="editor_room" />
    <exit alias="north" to="rooma">
      <inherit name="northdirection" />
    </exit>
  </object>
</asl>```
-------------------------------------------------------

K.V.
26 Feb 2018, 18:58

You are absolutely right!

I don't how that example still worked, but I made a new one and it had the same problem you describe with the map.

I fixed the library. (Sorry!!!)

Had to change this:
thisdict = DictionaryItem(player.grid_coordinates,"lift")

to this:
thisdict = DictionaryItem(player.grid_coordinates, this.name)

<?xml version="1.0"?>
<library>
  <!--
  If you are viewing this on GitHub and want to download it, right click on the RAW button
  just above, and select "Save link as..."
  -->


  <!--
  LiftLib v2.1
  
  Quest version: 5.6
  Written by: The Pixie, 2011-2018
  
  Version 2.1_and_a_half
  Modded by: KV, 2018
  Tutorial and notes here:
  https://github.com/ThePix/quest/wiki/Lift-Library
  -->




  <verb name="press">
    <property>press</property>
    <pattern>press;push</pattern>
    <defaultexpression>"You can't press " + object.article + "."</defaultexpression>
  </verb>
  
  
  

  <type name="liftroom">
    <current_floor type="int">1</current_floor>
    <usage_count type="int">0</usage_count>
    <lockexits type="boolean">false</lockexits>
    <goingup>The lift ascends to ###.</goingup>
    <goingdown>The lift descends to ###.</goingdown>
    <leavingmsg type="string"></leavingmsg>
    <samefloor>Nothing happens. Perhaps because you are already on ###.</samefloor>
	<attr name="changedcurrent_floor" type="script">
      oldvalue = this.last_floor
      currentvalue = this.current_floor
      change = oldvalue - currentvalue
      if (game.gridmap) {
	thisdict = DictionaryItem(player.grid_coordinates, this.name)
        if (Grid_GetRoomBooleanForPlayer(game.pov, this, "grid_isdrawn")) {
          dictionary remove (thisdict, "z")
          dictionary add (thisdict, "z", currentvalue*1.0+change)
          Grid_CalculateMapCoordinates (this, game.pov)
          Grid_Redraw  //THIS CLEARS ANY GRID FILLS!
          Grid_DrawPlayerInRoom (game.pov.parent)
        }
      }
    </attr>
    <onexit type="script">
      LeavingTheLift(this)
    </onexit>
  </type>
  
  
  

  <type name="liftbutton">
    <displayverbs type="simplestringlist">Press</displayverbs>
    <floor type="int">1</floor>
    <pressmsg>You press the button.</pressmsg>
    <press type="script">
      _PressButton(this, false)
    </press>
    <move type="script">
      // Invoke this to have the lift move to this button's destination
      // without any text appearing. The Arrival function is not called
      _PressButton(this, true)
    </move>
  </type>

  <type name="liftentrance">
    <runscript type="boolean">true</runscript>
    <script type="script">
      exit = ObjectListItem (ScopeExitsForRoom (this.to), 0)
      exit.to = game.pov.parent
	  game.pov.parent.last_floor = game.pov.parent.parent
      MoveObject (game.pov, this.to)
      //msg("about to check children of " + this.to.name)
      foreach (obj, GetDirectChildren (this.to)) {
        if (DoesInherit (obj, "liftbutton")) {
          if (obj.to = this.parent) {
            this.to.current_floor = obj.floor
            //msg("exit setting to " + obj.floor + " a " + TypeOf(obj.floor))
          }
        }
      }
    </script>
  </type>

  
  <function name="_PressButton" parameters="button, silently">
      exit = ObjectListItem (ScopeExitsForRoom (button.parent), 0)
      current = exit.to
      current_button = null
      foreach (o, GetDirectChildren(button.parent)) {
        if (o.destination = current) current_button = o
      }
      if (exit.to = button.destination) {
        moved = false
        s = button.parent.samefloor
      }
      else {
        moved = true
		button.parent.last_floor = button.parent.current_floor
        exit.to = button.destination
        if (button.parent.current_floor > button.floor) {
          s = button.parent.goingdown
        }
        else {
          s = button.parent.goingup
        }
        button.parent.current_floor = button.floor
        if (not current_button = null) {
          if (HasString(current_button, "departure")) {
            s = current_button.departure + " " + s
          }
        }
        if (HasString(button, "arrival")) {
          s = s + " " + button.arrival
        }
        button.parent.usage_count = button.parent.usage_count + 1
      }
      // prepend the button pressing message
      s = button.pressmsg + " " + s
      // Swap ### for the floor name
      if (HasString(button, "floorname")) {
        s = Replace (s, "###", ToString (button.floorname))
      }
      else {
        s = Replace (s, "###", "floor " + button.floor)
      }
      if (not silently) {
        Arrival(button, s, moved)
      }
	</function>

  
  


  <!--
  This is called when the player presses a button (but not
  when the lift is moved another time).
  You can override this to have it print in a fancy way, or to have it do something when
  the lift moves.
  -->
  <function name="Arrival" parameters="button, s, moved">
    msg(s)
	</function>


  <function name="LeavingTheLift" parameters="this">
    if (not this.leavingmsg = "") {
      msg (this.leavingmsg)
    }
	</function>


  <function name="LiftRoom" type="object" parameters="button">
    if (DoesInherit(button, "liftroom")) {
      return (button)
    }
    return (button.parent)
	</function>

  <function name="LiftExit" type="object" parameters="button">
    return (ObjectListItem (ScopeExitsForRoom (LiftRoom(button)), 0))
	</function>

  <function name="LiftCurrentFloor" type="object" parameters="button">
    exit = LiftExit(button)
    return (exit.to)
	</function>

  <function name="LiftCurrentButton" type="object" parameters="button">
    current = LiftCurrentFloor(button)
    current_button = null
    foreach (o, GetDirectChildren(LiftRoom(button))) {
      if (o.destination = current) current_button = o
    }
    return (current_button)
	</function>

  <function name="LiftAllButtons" type="objectlist" parameters="button">
    ol = NewObjectList()
    foreach (o, GetDirectChildren(LiftRoom(button))) {
      if (DoesInherit(o, "liftbutton")) list add(ol, o)
    }
    return (ol)
	</function>

  <function name="LiftAllEntrances" type="objectlist" parameters="button">
    ol = NewObjectList()
    foreach (o, LiftAllButtons(button)) {
      list add(ol, GetObject(GetExitByLink (o.destination, LiftRoom(button))))
    }
    return (ol)
	</function>

  <function name="LiftCurrentEntrance" type="object" parameters="button">
    return (GetObject(GetExitByLink (LiftCurrentFloor(button), LiftRoom(button))))
	</function>


 
  
  
 <!-- =================================================== -->
  <!-- Tabs -->

  <tab>
    <parent>_ObjectEditor</parent>
    <caption>Lift</caption>
    <mustnotinherit>defaultplayer</mustnotinherit>

    <control>
      <controltype>dropdowntypes</controltype>
      <caption>Type</caption>
      <types>*=None; liftroom=Lift; liftbutton=Lift Button; liftentrance=Lift Entrance</types>
      <width>150</width>
    </control>

    <control>
      <controltype>textbox</controltype>
      <caption>Same floor message</caption>
      <attribute>samefloor</attribute>
      <mustinherit>liftroom</mustinherit>
    </control>

    <control>
      <controltype>textbox</controltype>
      <caption>The going up message</caption>
      <attribute>goingup</attribute>
      <mustinherit>liftroom</mustinherit>
    </control>

    <control>
      <controltype>textbox</controltype>
      <caption>The going down message</caption>
      <attribute>goingdown</attribute>
      <mustinherit>liftroom</mustinherit>
    </control>

    <control>
      <controltype>textbox</controltype>
      <caption>The leaving message</caption>
      <attribute>leavingmsg</attribute>
      <mustinherit>liftroom</mustinherit>
    </control>

    <control>
      <controltype>checkbox</controltype>
      <caption>Lock exit after entering lift</caption>
      <attribute>lockexits</attribute>
      <mustinherit>liftroom</mustinherit>
    </control>

    <control>
      <controltype>textbox</controltype>
      <caption>Departure message</caption>
      <attribute>departure</attribute>
      <mustinherit>editor_room</mustinherit>
      <mustinherit>liftbutton</mustinherit>
    </control>

    <control>
      <controltype>textbox</controltype>
      <caption>Arrival message</caption>
      <attribute>arrival</attribute>
      <mustinherit>liftbutton</mustinherit>
    </control>

    <control>
      <controltype>textbox</controltype>
      <caption>Press message</caption>
      <attribute>pressmsg</attribute>
      <mustinherit>liftbutton</mustinherit>
    </control>

    <control>
      <controltype>textbox</controltype>
      <caption>Floor name</caption>
      <attribute>floorname</attribute>
      <mustinherit>liftbutton</mustinherit>
    </control>


    <control>
      <controltype>objects</controltype>
      <caption>Destination</caption>
      <attribute>destination</attribute>
      <mustinherit>liftbutton</mustinherit>
    </control>

    <control>
      <controltype>number</controltype>
      <caption>Floor</caption>
      <attribute>floor</attribute>
      <width>100</width>
      <mustinherit>liftbutton</mustinherit>
    </control>

  </tab>
</library>

baskham
26 Feb 2018, 19:36

YAY!!!!

It works!!
In all situations.

Thank you.
United we stand :-)


K.V.
26 Feb 2018, 22:00

You're welcome!

Thank you for going through all the frustration which led to the fix!


Also note:

I only fiddled with Pixie's library because he's got quite the agenda lately. (Ahem. I won't mention Quest 5.8.)

At some point, he will more than likely post an updated version of LiftLib which fixes the bugs and adds more functionality than we just did, and in a more efficient manner.


baskham
22 Mar 2018, 19:26

:-(

I now discovered a problem with this.

If you move around on the original floor, the grid is drawn correctly.
Then if you take the lift to another floor, the already drawn map is still visible but toned down (or grayed out or whatever :-))
And then when you leave the lift and move around the map of the new floor is drawn on top of the toned down map (but drawn correctly).

This is very confusing to some of my testers, as they don't realize that the toned down rooms should be ignored.

Is there anyway to just erase the map when you go to a new floor?
But of course when you return to a floor, the map should once again be drawn with the rooms you have already visited...