Inform - Support - Patches

About Patches  

Compiler  
Library  

DM4 Errata  

Issue L61021

GoSub routine broken
Submitted by: Graham Fyffe     Appeared in: Library 6/10 or before     Fixed in: -
Problem

The GoSub routine is broken with respect to handling doors. One of the bugs involved completely broke the use of "go door" in some situations...

Solution

Fixed the Gosub routine in VerbLibm.h (with comments):

  [ GoSub src dest k df movewith thedir old_loc;
    !// [GLYPH] first thing I did was use clearer variable names :)
    !// [GLYPH] plus I added some comments so I could see what was happening

    !// [GLYPH] this was "second" instead of "noun"... that didn't seem right
    if (noun ~= 0 && noun notin Compass
        && ObjectIsUntouchable(noun)) return;

    !// handle being inside darkness or being inside a vehicle
    old_loc = location;
    movewith=0;
    src=parent(player);
    if ((location~=thedark && src~=location)
        || (location==thedark && src~=real_location))
    {
        dest=location;
        if (location==thedark) location=real_location;
        k=RunRoutines(src,before);
        if (k~=3) location=dest;
        if (k==1) { movewith=src; src=parent(src); }
        else { if (k==0) L__M(##Go,1,src); rtrue; }
    }

    !// [GLYPH] this next block has been rearranged (bugfixed)
    if (noun has door) dest = noun;  !// handle direct references to doors
    else    !// handle non-door movement, possibly leading to a door
    {
        thedir=noun.door_dir;
        if (ZRegion(thedir)==2) thedir=RunRoutines(noun,door_dir);
        dest=src.thedir; k=ZRegion(dest);
        if (k==3) { print (string) dest; new_line; rfalse; }
        if (k==2) { dest=RunRoutines(src,thedir); if (dest==1) rtrue; }
        if (k==0 || dest==0)
        {   if (src.cant_go ~= 0) PrintOrRun(src, cant_go);
            rfalse;
        }
    }

    !// handle movement through doors
    if (dest has door)
    {
        if (dest has concealed) return L__M(##Go,2);
        if (dest hasnt open)
        {
            if (noun==u_obj) return L__M(##Go,3,dest);
            if (noun==d_obj) return L__M(##Go,4,dest);
            return L__M(##Go,5,dest);
        }
        !// resolve destination through door
        k=RunRoutines(dest,door_to);
        if (k==0) return L__M(##Go,6,dest);
        if (k==1) rtrue;
        dest = k;
    }

    !// [GLYPH] from here on she's pretty good
    if (movewith==0) move player to dest; else move movewith to dest;
    location=dest; MoveFloatingObjects();
    df=OffersLight(dest);
    if (df~=0) { location=dest; real_location=dest; lightflag=1; }
    else
    {   if (old_loc == thedark)
        {   DarkToDark();
            if (deadflag~=0) rtrue;
        }
        real_location=dest;
        location=thedark; lightflag=0;
    }
    if (AfterRoutines()==1) rtrue;
    if (keep_silent==1) rtrue;
    LookSub(1);
  ];
Update (by Neil Cerutti)

Graham fails to demonstrate any bug in the library. In fact, his new version introduces two new bugs.

1. He obliterates the check to see if a pushed item is touchable:

  [ GoSub src dest k df movewith thedir old_loc;
      !// [GLYPH] first thing I did was use clearer variable names :)
      !// [GLYPH] plus I added some comments so I could see what was happening
      !// [GLYPH] this was "second" instead of "noun"... that didn't seem right

      !// [NEIL] Not surprisingly, it *was* right. It checks to see if second is defined -- if it is,
      !// that means the player is pushing an object using the PushDir action. This object
      !// must be touchable.
      if (noun ~= 0 && noun notin Compass
          && ObjectIsUntouchable(noun)) return;

2. The other change he inserted only serves to cover up programmer error (you will run into trouble with the standard GoSub if the door_dir property of your door is incorrect -- all doors must effectively point to themselves through the door_dir property). This may seem silly, but it is that way for a good reason: the direction properties of rooms.

This change will prevent the direction property of the room from being run when a player enters a door by saying "enter door" or "go door". This will cause problems for many Inform programmers who depend on them being run. For example, his change breaks the Inform port of Ditch Day Drifter.

GoSub is one of the most overloaded and complicated action routines in the library, and it shouldn't be altered unless one understands fully what one is doing.

Conclusion: this is not thought to be an issue.


Last updated 17 April 2013. This web site has not been fully supported since April 2008. Information may be out of date. This page was originally managed by Roger Firth.