Games-Axmud

 view release on metacpan or  search on metacpan

lib/Games/Axmud/Obj/WorldModel.pm  view on Meta::CPAN

            mapFont                     => 'Sans',
            roomTagRatio                => 1,
            roomGuildRatio              => 0.7,
            exitTagRatio                => 0.7,
            labelRatio                  => 0.8,
            roomTextRatio               => 0.7,

            # $self->deleteRegions, ->deleteRooms, ->deleteExits and ->deleteLabels all make a call
            #   to GA::Win::Map->setSelectedObj to make sure there are no selected objects in the
            #   automapper window(s)
            # A single call to ->deleteRegions could cause thousands of calls to ->deleteExits,
            #   each of them calling GA::Win::Map->setSelectedObj in turn
            # In that case, we only need a single call to GA::Win::Map->setSelectedObj. This flag is
            #   set to TRUE when ->deleteRegions is called, and reset back to FALSE when that
            #   function is finished. When the flag is TRUE, no time-wasting calls to
            #   GA::Win::Map->setSelectedObj are made
            blockUnselectFlag           => FALSE,
        };

        # Bless the object into existence
        bless $self, $class;

        # Set the light status list
        $self->{lightStatusList}        = $self->{constLightStatusList};

        # Set map size (based on the values immediately above)
        $self->{defaultMapWidthPixels}
            = $self->{defaultGridWidthBlocks} * $self->{defaultBlockWidthPixels};
        $self->{defaultMapHeightPixels}
            = $self->{defaultGridHeightBlocks} * $self->{defaultBlockHeightPixels};

        # Create a default region scheme object
        $self->ivPoke(
            'defaultSchemeObj',
            Games::Axmud::Obj::RegionScheme->new($session, $self, 'default'),
        );
        $self->ivAdd('regionSchemeHash', 'default', $self->defaultSchemeObj);

        # Create some map label styles
        $self->addLabelStyle($session, 'Style 1', $self->{defaultMapLabelColour});
        $self->addLabelStyle($session, 'Style 2', '#FF40E0');
        $self->addLabelStyle($session, 'Style 3', '#000000', undef, 2);
        $self->addLabelStyle($session, 'Style 4', '#000000', undef, 4);
        $self->{mapLabelStyle}          = 'Style 1';

        # Set room filters and room flags
        $self->setupRoomFlags($session);

        # Create a painter object - a non-model GA::ModelObj::Room used to 'paint' other rooms
        #   by copying its IVs into theirs
        $self->resetPainter($session);

        return $self;
    }

    ##################
    # Methods

    # Methods called by GA::Session->spinMaintainLoop, etc

    sub updateRegionPaths {

        # Called by GA::Session->spinMaintainLoop, $self->findUniversalPath and
        #   GA::EditWin::Regionmap->boundaries1Tab_addButtons
        # Uses the exit numbers stored in $self->updateBoundaryHash, ->updatePathHash and
        #   ->deleteBoundaryHash (if any) to create, modify or delete region paths for the exits'
        #   parent regions
        #
        # Expected arguments
        #   $session        - The calling function's GA::Session
        #
        # Return values
        #   'undef' on improper arguments
        #   1 otherwise

        my ($self, $session, $check) = @_;

        # Local variables
        my (
            @exitList, @newModList,
            %boundaryHash, %deleteHash, %regionmapHash, %regionNameHash, %otherHash,
            %otherRegionmapHash,
        );

        # Check for improper arguments
        if (! defined $session || defined $check) {

            return $axmud::CLIENT->writeImproper($self->_objClass . '->updateRegionPaths', @_);
        }

        # $self->connectRegionBrokenExit can open 'dialogue' windows; while the window is open, the
        #   GA::Session's timer loop can still call this function. Ignore any such calls until the
        #   dialogue connect operation has completed
        if ($self->updateDelayFlag) {

            return undef;
        }

        # Import the hashes (for quick lookup)
        %boundaryHash = $self->updateBoundaryHash;
        %otherHash = $self->updatePathHash;
        %deleteHash = $self->deleteBoundaryHash;

        # First deal with all region exits which have been created, modified or deleted since the
        #   last spin of the timer loop (if any)
        if (%boundaryHash) {

            # Get a sorted list of exit numbers, because when two region exits in the same region
            #   lead to the same other region, the one with the lowest exit model number (usually
            #   the first one created) is used as the super-region exit, by default
            @exitList = sort {$a <=> $b} (keys %boundaryHash);

            OUTER: foreach my $exitNum (@exitList) {

                my ($regionName, $regionmapObj, $exitObj, $roomObj, $newRegionObj);

                $regionName = $boundaryHash{$exitNum};
                $regionmapObj = $self->ivShow('regionmapHash', $regionName);
                if (! $regionmapObj) {

                    # If the region is being deleted, don't need to bother with its super-region

lib/Games/Axmud/Obj/WorldModel.pm  view on Meta::CPAN

        ($pathRoomListRef, $pathExitListRef) = $self->findPath(
            $startRoomObj,
            $stopRoomObj,
            $safeFlag,          # Avoid hazards, or not
            undef,
            TRUE,               # Don't use adjacent regions
        );

        # If there is actually a path between the two rooms...
        if (@$pathRoomListRef) {

            # Save it
            $newPathObj = Games::Axmud::Obj::RegionPath->new(
                $session,
                $startExitObj->number,
                $stopExitObj->number,
                $pathRoomListRef,
                $pathExitListRef,
            );

            if ($newPathObj) {

                # Store the path, replacing any previously-existing path between the same two
                #   exits
                if (! $safeFlag) {

                    $regionmapObj->storePath(
                        'regionPathHash',
                        $startExitObj,
                        $stopExitObj,
                        $newPathObj,
                    );

                } else {

                    $regionmapObj->storePath(
                        'safeRegionPathHash',
                        $startExitObj,
                        $stopExitObj,
                        $newPathObj,
                    );
                }
            }

        } else {

            # Even though a new path could not be found, the existing path is invalid, and must be
            #   removed
            $exitString = $pathObj->startExit . '_' . $pathObj->stopExit;

            if (! $safeFlag) {
                $regionmapObj->removePaths($exitString, 'regionPathHash');
            } else {
                $regionmapObj->removePaths($exitString, 'safeRegionPathHash');
            }
        }

        return 1;
    }

    sub updateModelBuffers {

        # Called by GA::Session->spinMaintainLoop
        # When a model object or exit object is deleted, the number is temporarily stored in
        #   $self->modelBufferList or $self->exitBufferList
        # If either IV contains any numbers, copy them into ->modelDeletedList or ->exitDeletedList
        #   so that they're available for re-use
        #
        # Expected arguments
        #   (none besides $self)
        #
        # Return values
        #   'undef' on improper arguments
        #   1 otherwise

        my ($self, $check) = @_;

        # Check for improper arguments
        if (defined $check) {

            return $axmud::CLIENT->writeImproper($self->_objClass . '->updateModelBuffers', @_);
        }

        if ($self->modelBufferList) {

            $self->ivPush('modelDeletedList', sort {$a <=> $b} ($self->modelBufferList));
            $self->ivEmpty('modelBufferList');
        }

        if ($self->exitBufferList) {

            $self->ivPush('exitDeletedList', sort {$a <=> $b} ($self->exitBufferList));
            $self->ivEmpty('exitBufferList');
        }

        return 1
    }

    sub updateRegionLevels {

        # Called by GA::Session->spinMaintainLoop
        # When a room model object or map label is added, moved or deleted, the parent regionmap's
        #   name is temporarily stored in $self->checkLevelsHash
        # Ask each regionmap to re-calculate its highest and lowest occupied levels
        #
        # Expected arguments
        #   (none besides $self)
        #
        # Return values
        #   'undef' on improper arguments
        #   1 otherwise

        my ($self, $check) = @_;

        # Local variables
        my @mapWinList;

        # Check for improper arguments
        if (defined $check) {

            return $axmud::CLIENT->writeImproper($self->_objClass . '->updateRegionLevels', @_);
        }

        # Collect a list of automapper windows used by this world model now (so we only have to do
        #   it once)
        @mapWinList = $self->collectMapWins();

        OUTER: foreach my $regionName ($self->ivKeys('checkLevelsHash')) {

            my ($regionmapObj, $high, $low);

            $regionmapObj = $self->ivShow('regionmapHash', $regionName);
            if (! $regionmapObj) {

                # Region has just been deleted, so move on to the next one
                next OUTER;
            }

            # Check every room in the map, finding the highest and lowest occupied level
            foreach my $roomNum ($regionmapObj->ivValues('gridRoomHash')) {

                my $roomObj = $self->ivShow('modelHash', $roomNum);
                if ($roomObj) {

                    if (! defined $high || $high < $roomObj->zPosBlocks) {

                        $high = $roomObj->zPosBlocks;
                    }

                    if (! $low || $low > $roomObj->zPosBlocks) {

                        $low = $roomObj->zPosBlocks;
                    }
                }
            }

            # Likewise check every label
            foreach my $labelObj ($regionmapObj->ivValues('gridLabelHash')) {

lib/Games/Axmud/Obj/WorldModel.pm  view on Meta::CPAN

        if ($regionmapObj->fetchRoom($xPosBlocks, $yPosBlocks, $zPosBlocks)) {

            return undef;
        }

        # If $name wasn't specified, use a temporary name
        if (! $name) {

            $name = '<unnamed room>';
        }

        # Create the new room object
        $roomObj = Games::Axmud::ModelObj::Room->new(
            $session,
            $name,
            'model',
            $regionmapObj->number,
        );

        if (! $roomObj) {

            return undef;
        }

        # Add the room object to the model
        if (! $self->addToModel($roomObj)) {

            # Object could not be added
            return undef;
        }

        # Set the room's position
        $roomObj->ivPoke('xPosBlocks', $xPosBlocks);
        $roomObj->ivPoke('yPosBlocks', $yPosBlocks);
        $roomObj->ivPoke('zPosBlocks', $zPosBlocks);

        # Add the room to its regionmap
        $regionmapObj->storeRoom($roomObj);

        # Update any GA::Win::Map objects using this world model (if allowed)
        if ($updateFlag) {

            foreach my $mapWin ($self->collectMapWins()) {

                # Redraw the room
                $mapWin->markObjs('room', $roomObj);
                $mapWin->doDraw();

                # The regionmap's highest/lowest occupied levels need to be recalculated
                $self->ivAdd('checkLevelsHash', $regionmapObj->name, undef);
                # Sensitise/desensitise menu bar/toolbar items, depending on current conditions (as
                #   a response to this calculation)
                $mapWin->restrictWidgets();
            }
        }

        # Operation complete
        return $roomObj;
    }

    sub updateRoom {

        # Called by GA::Obj::Map->updateRoom, when the Automapper window is in 'update' mode, to
        #   adjust the properties of a room object in the world model to match those of
        #   the Locator task's non-model current room
        # The properties adjusted depend on various flags
        #
        # Expected arguments
        #   $session
        #       - The calling function's GA::Session
        #   $updateFlag
        #       - Flag set to TRUE if all Automapper windows using this world model should be
        #           updated now, FALSE if not (in which case, they can be updated later by the
        #           calling function, when it is ready)
        #   $modelRoomObj
        #       - A GA::ModelObj::Room in the world model
        #
        # Optional arguments
        #   $connectRoomObj, $connectExitObj, $standardDir
        #       - When the calling function was in turn called by GA::Obj::Map->createNewRoom, the
        #           room from which the character arrived and the exit obj/standard direction used
        #           (if known). Used when temporarily allocating primary directions to unallocated
        #           exits
        #
        # Return values
        #   'undef' on improper arguments, if the Locator task doesn't exist, if it doesn't know the
        #       current location or if we're not in 'update' mode
        #   1 otherwise

        my (
            $self, $session, $updateFlag, $modelRoomObj, $connectRoomObj, $connectExitObj,
            $standardDir, $check,
        ) = @_;

        # Local variables
        my (
            $taskObj, $taskRoomObj, $name, $terrain, $roomFlag,
            @titleList, @drawList,
        );

        # Check for improper arguments
        if (! defined $session || ! defined $modelRoomObj || defined $check) {

            return $axmud::CLIENT->writeImproper($self->_objClass . '->updateRoom', @_);
        }

        # Import the Locator task and its current room
        $taskObj = $session->locatorTask;
        if ($taskObj) {

            $taskRoomObj = $taskObj->roomObj;
        }

        # If the Locator task doesn't exist, or if it doesn't know the current location, we can't
        #   use the location's properties
        if (! $taskRoomObj) {

            return undef;
        }

        # Update the room title(s) (if the Locator task knows any, and if we're allowed)

lib/Games/Axmud/Obj/WorldModel.pm  view on Meta::CPAN

                        && $otherExitObj->mapDir eq $standardDir
                    ) {
                        # The room's existing exit is using the map direction we need
                        $reallocateExitObj = $otherExitObj;
                        last OUTER;
                    }
                }
            }
        }

        # Add the new exit object to the room
        $roomObj->ivAdd('exitNumHash', $dir, $exitObj->number);
        $exitObj->ivPoke('parent', $roomObj->number);

        @dirList = $roomObj->ivKeys('exitNumHash');
        @sortedList = $dictObj->sortExits(@dirList);
        $roomObj->ivPoke('sortedExitList', @sortedList);

        # If an existing exit has been supplanted, allocate it a different map direction
        if ($reallocateExitObj) {

            $regionFlag = $reallocateExitObj->regionFlag;
            $regionObj = $self->ivShow('modelHash', $roomObj->parent);

            $reallocateExitObj->ivUndef('mapDir');
            $reallocateExitObj->ivPoke('drawMode', 'primary');

            $self->allocateCardinalDir($session, $roomObj, $reallocateExitObj);

            # Any region paths using the reallocated exit will have to be updated
            $self->ivAdd('updatePathHash', $reallocateExitObj->number, $regionObj->name);
            if ($regionFlag || $reallocateExitObj->regionFlag) {

                $self->ivAdd('updateBoundaryHash', $reallocateExitObj->number, $regionObj->name);
            }
        }

        # If a checked direction in this (primary or secondary) direction existed, remove its entry
        $roomObj->ivDelete('checkedDirHash', $exitObj->dir);

        # Set the exit type (e.g. 'primaryDir', 'primaryAbbrev', etc)
        $exitObj->ivPoke(
            'exitType',
            $session->currentDict->ivShow('combDirHash', $exitObj->dir),
        );

        # Update any GA::Win::Map objects using this world model (if allowed)
        if ($updateFlag) {

            foreach my $mapWin ($self->collectMapWins()) {

                # Redraw the exit
                $mapWin->markObjs('exit', $exitObj);
                $mapWin->doDraw();
            }
        }

        return $exitObj;
    }

    sub updateExit {

        # Called by GA::Win::Map->updateRoom
        # The current Locator task has a non-model room with non-model exits. Given one of those
        #   exits, create a new exit object and add it to the world model via a call to
        #   $self->addExit
        # However, if the world model room object already has an exit in the same direction, don't
        #   replace it - just update its IVs
        #
        # Expected arguments
        #   $session        - The calling function's GA::Session
        #   $updateFlag     - Flag set to TRUE if all Automapper windows using this world model
        #                       should be updated now, FALSE if not (in which case, they can be
        #                       updated later by the calling function, when it is ready)
        #   $modelRoomObj   - The room object in the world model to which the new exit will belong
        #   $taskRoomObj    - The current Locator task's non-model room object
        #   $taskExitObj    - The non-model exit object belonging to $taskRoomObj which we need to
        #                       copy
        #
        # Optional arguments
        #   $convertDir     - If $taskExitObj's nominal direction is a relative direction, the
        #                       calling function has converted it into a standard primary direction
        #                       like 'north', depending on which direction the character is facing.
        #                       'undef' for non-relative directions
        #
        # Return values
        #   'undef' on improper arguments or if the function tries and fails to create a new exit
        #   Otherwise, returns the model number of the newly-added exit object

        my (
            $self, $session, $updateFlag, $modelRoomObj, $taskRoomObj, $taskExitObj, $convertDir,
            $check,
        ) = @_;

        # Local variables
        my ($useDir, $modelExitNum, $modelExitObj, $standardDir, $regionObj);

        # Check for improper arguments
        if (
            ! defined $session || ! defined $updateFlag || ! defined $modelRoomObj
            || ! defined $taskRoomObj || ! defined $taskExitObj || defined $check
        ) {
            return $axmud::CLIENT->writeImproper($self->_objClass . '->updateExit', @_);
        }

        # Any relative direction has been converted into a standard primary direction like 'north'
        # During this function, if $convertDir was specified, use the corresponding custom
        #   direction, otherwise use the exit's true nominal direction
        if (defined $convertDir) {
            $useDir = $session->currentDict->ivShow('primaryDirHash', $convertDir);
        } else {
            $useDir = $taskExitObj->dir;
        }

        # Does the world model room object already have an exit in this direction?
        if (! $modelRoomObj->ivExists('exitNumHash', $useDir)) {

            # It doesn't, so add a new one
            $modelExitObj = $self->addExit(
                $session,
                FALSE,              # Don't update Automapper windows now

lib/Games/Axmud/Obj/WorldModel.pm  view on Meta::CPAN


                $self->unsetBrokenExit(
                    FALSE,      # Don't update Automapper windows
                    $twinExitObj,
                    undef,
                );
            }
        }

        # Update any GA::Win::Map objects using this world model (if allowed)
        if ($updateFlag) {

            push (@redrawList,
                'room', $roomObj,
                'room', $parentRoomObj,
            );

            # Only draw a paired twin room (and its exit) a special colour, if the exit is a normal
            #   (unbent) broken exit or a region exit - the special colour is only for exits not
            #   drawn with a line
            if (
                $pairedTwinRoom
                && (
                    (! $pairedTwinExit->brokenFlag && ! $pairedTwinExit->regionFlag)
                    || ($pairedTwinExit->brokenFlag && $pairedTwinExit->bentFlag)
                )
            ) {
                $pairedTwinRoom = undef;
            }

            # If the paired twin room is still to be drawn a different colour, mark it to be
            #   redrawn
            if ($pairedTwinRoom) {

                push (@redrawList, 'room', $pairedTwinRoom);
            }

            foreach my $mapWin ($self->collectMapWins()) {

                # Mark the paired room/exit (if set) to be drawn a different colour
                if ($pairedTwinRoom) {

                    $mapWin->set_pairedTwinRoom($pairedTwinRoom);
                    $mapWin->set_pairedTwinExit($pairedTwinExit);
                }

                # Redraw affected rooms immediately
                $mapWin->markObjs(@redrawList);
                $mapWin->doDraw();
            }
        }

        # Allow $self->updateRegionPaths to be called again
        $self->ivPoke('updateDelayFlag', FALSE);

        return 1;
    }

    # Modify model objects - rooms

    sub updateRegion {

        # Can be called by anything to force any Automapper windows to redraw regions (though at the
        #   moment, only code in 'edit' windows calls this function)
        #
        # Expected arguments
        #   (none besides $self)
        #
        # Optional arguments
        #   $region     - The name of a regionmap. If specified, only this region is redrawn in
        #                   every Automapper window (but if it's not already drawn, even partially,
        #                   it's not redrawn). If not specified, all drawn regions in each
        #                   Automapper window are redrawn
        #
        # Return values
        #   'undef' on improper arguments or if the specified region doesn't exist
        #   1 otherwise

        my ($self, $region, $check) = @_;

        # Local variables
        my $regionmapObj;

        # Check for improper arguments
        if (defined $check) {

            return $axmud::CLIENT->writeImproper($self->_objClass . '->updateRegion', @_);
        }

        if ($region) {

            # Find the equivalent regionmap
            $regionmapObj = $self->ivShow('regionmapHash', $region);
            if (! $regionmapObj) {

                # Nothing more we can do
                return undef;
            }
        }

        # Update each Automapper window in turn
        foreach my $mapWin ($self->collectMapWins()) {

            if (! $regionmapObj) {

                # Redraw all drawn regions
                $mapWin->redrawRegions();

            } elsif ($mapWin->ivExists('parchmentHash', $regionmapObj->name)) {

                # Redraw the specified region (if it's drawn in this automapper window). The TRUE
                #   argument means 'don't redraw other regions'
                $mapWin->redrawRegions($regionmapObj, TRUE);
            }
        }

        return 1;
    }

    sub updateMaps {

        # Can be called by anything in the automapper object (GA::Obj::Map) and the Automapper
        #   window (GA::Win::Map) to update every Automapper window using this world model
        # Usually called after other calls to this world model object, in which the $updateFlag
        #   argument was set to FALSE - the calling function is now ready for the Automapper windows
        #   to be updated
        #
        # Expected arguments
        #   (none besides $self)
        #
        # Optional arguments
        #   @list       - A list to send to each Automapper window's ->markObjs, in the form
        #                   (type, object, type, object...)
        #               - If it's an empty list, nothing is marked to be drawn; GA::Win::Map->doDraw
        #                   is still called in each automapper window, in the expectation that
        #                   something has already been marked to be drawn
        #
        # Return values
        #   'undef' on improper arguments
        #   1 otherwise

        my ($self, @list) = @_;

        # (No improper arguments to check)

        foreach my $mapWin ($self->collectMapWins()) {

            if (@list) {

                $mapWin->markObjs(@list);
            }

            $mapWin->doDraw();
        }

        return 1;
    }

    sub updateMapMenuToolbars {

        # Can be called by anything in the automapper object (GA::Obj::Map) and the Automapper
        #   window (GA::Win::Map) to update every Automapper window using this world model
        # Also called by the painter's edit window, when ->saveChanges is applied
        # Redraws the menu bars and/or toolbars in all automapper windows using this world model
        #
        # Expected arguments
        #   (none besides $self)
        #
        # Return values
        #   'undef' on improper arguments
        #   1 otherwise

        my ($self, $check) = @_;

        # Check for improper arguments
        if (defined $check) {

            return $axmud::CLIENT->writeImproper($self->_objClass . '->updateMapMenuToolbars', @_);
        }

        foreach my $mapWin ($self->collectMapWins()) {

            $mapWin->redrawWidgets('menu_bar', 'toolbar');
        }

        return 1;
    }

    sub updateMapExit {

        # Called by several of this object's functions to update a single exit (and its twin) in
        #   every Automapper window using this world model
        #
        # Expected arguments
        #   $exitObj        - The exit object to update
        #
        # Optional arguments
        #   $twinExitObj    - The exit's twin object, if known (if 'undef', this function looks up
        #                       for twin exit object)
        #
        # Return values
        #   'undef' on improper arguments
        #   1 otherwise

        my ($self, $exitObj, $twinExitObj, $check) = @_;

        # Local variables
        my @list;

        # Check for improper arguments
        if (! defined $exitObj || defined $check) {

            return $axmud::CLIENT->writeImproper($self->_objClass . '->updateMapExit', @_);
        }

        # If the exit has a twin, that must be redrawn, too
        @list = ('exit', $exitObj);

        if (! $twinExitObj && $exitObj->twinExit) {

            $twinExitObj = $self->ivShow('exitModelHash', $exitObj->twinExit);
        }

        if ($twinExitObj) {

            push (@list, 'exit', $twinExitObj);
        }

        foreach my $mapWin ($self->collectMapWins()) {

            # Redraw the objects
            $mapWin->markObjs(@list);
            $mapWin->doDraw();
        }

        return 1;
    }

    sub updateMapLabels {

        # Called by GA::EditWin::MapLabelStyle->saveChanges and $self->deleteLabelStyle to redraw
        #   all labels in every Automapper using this world model (assuming that the map label style
        #   has been modified)
        #
        # Expected arguments
        #   (none besides $self)
        #
        # Return values
        #   'undef' on improper arguments
        #   1 otherwise

        my ($self, $check) = @_;

        # Local variables
        my @list;

        # Check for improper arguments
        if (defined $check) {

            return $axmud::CLIENT->writeImproper($self->_objClass . '->updateMapLabels', @_);
        }

        foreach my $mapWin ($self->collectMapWins()) {

            if ($mapWin->currentRegionmap) {

                foreach my $labelObj ($mapWin->currentRegionmap->ivValues('gridLabelHash')) {

                    push (@list, 'label', $labelObj);
                }

                # Redraw the objects
                $mapWin->markObjs(@list);
                $mapWin->doDraw();
            }
        }

        return 1;
    }

    sub connectRooms {

        # Called by GA::Obj::Map->autoProcessNewRoom, ->useExistingRoom,
        #   GA::Obj::Map->createNewRoom, $self->connectRegions or any other function
        # Given two room objects in the world model, and the command we use to move from one to the
        #   other, connect the rooms by modifying their exit object's IVs
        #
        # Expected arguments
        #   $session        - The calling function's GA::Session
        #   $updateFlag     - Flag set to TRUE if all Automapper windows using this world model
        #                       should be updated now, FALSE if not (in which case, they can be
        #                       updated later by the calling function, when it is ready)
        #   $departRoomObj  - The GA::ModelObj::Room from which the character left
        #   $arriveRoomObj  - The GA::ModelObj::Room to which the character arrived
        #   $dir            - The command used to move (e.g. 'north', 'cross bridge')
        #
        # Optional arguments
        #   $mapDir         - How the exit is drawn on the map - matches a standard primary
        #                       direction (e.g. 'north', 'south', 'up'). If not specified, the exit

lib/Games/Axmud/Obj/WorldModel.pm  view on Meta::CPAN

                    }

                    if (
                        # Gridblock actually exists
                        $regionmapObj->checkGridBlock($thisXPos, $thisYPos, $zPos)
                        # ...and is not occupied
                        && ! $regionmapObj->fetchRoom($thisXPos, $thisYPos, $zPos)
                    ) {
                        # Success!
                        $useXPos = $thisXPos;
                        $useYPos = $thisYPos;
                        last OUTER;
                    }
                }
            }
        }

        if (! defined $useXPos) {

            # No empty gridblock found
            return @emptyList;
        }

        # Empty gridblock found at $useXPos, $useYPos, $zPos
        #.
        if (! $slideRoomObj) {

            # For some auto-slide modes, return the location of the empty gridblock, so a new room
            #   can be created there
            return ($useXPos, $useYPos, $zPos);

        } else {

            # For others, move an existing room to the empty gridblock

            # $self->moveRoomsLabels expects a room list, stored as a hash
            $roomHash{$slideRoomObj->number} = $slideRoomObj;

            if (
                ! $self->moveRoomsLabels(
                    $session,
                    $updateFlag,
                    $regionmapObj,
                    $regionmapObj,
                    ($useXPos - $slideRoomObj->xPosBlocks),
                    ($useYPos - $slideRoomObj->yPosBlocks),
                    0,
                    \%roomHash,
                    \%emptyHash,            # No labels to move
                )
            ) {
                return @emptyList;
            } else {
                return ($useXPos, $useYPos, $zPos, $slideRoomObj);
            }
        }

        return 1;
    }

    sub updateVisitCount {

        # Called by several functions in the automapper object (GA::Obj::Map) and the Automapper
        #   window (GA::Win::Map)
        # Increments the number of character visits to a room, if allowed
        #
        # Expected arguments
        #   $session    - The calling function's GA::Session
        #   $updateFlag - Flag set to TRUE if all Automapper windows using this world model should
        #                   be updated now, FALSE if not (in which case, they can be updated later
        #                   by the calling function, when it is ready)
        #   $number     - The model number of the room object to update
        #
        # Return values
        #   'undef' on improper arguments, if the model object doesn't exist, if it isn't a room, if
        #       $self->countVisitsFlag is set to TRUE (meaning we don't count character visits) or
        #       if the current session doesn't have a current character profile
        #   1 otherwise

        my ($self, $session, $updateFlag, $number, $check) = @_;

        # Local variables
        my ($roomObj, $charName);

        # Check for improper arguments
        if (! defined $session || ! defined $updateFlag || ! defined $number || defined $check) {

            return $axmud::CLIENT->writeImproper($self->_objClass . '->updateVisitCount', @_);
        }

        # Check that we're allowed to count character visits and that the current session has a
        #   current character profile
        if (! $self->countVisitsFlag || ! $session->currentChar) {

            return undef;
        }

        # Get the model object
        $roomObj = $self->ivShow('modelHash', $number);
        if (! $roomObj || $roomObj->category ne 'room') {

            return undef;
        }

        # Update the room
        $charName = $session->currentChar->name;

        if (! $roomObj->ivExists('visitHash', $charName)) {

            # First visit to this room
            $roomObj->ivAdd('visitHash', $charName, 1);

        } else {

            # A return visit to this room
            $roomObj->ivIncHash('visitHash', $charName);
        }

        # Update any GA::Win::Map objects using this world model (if allowed)
        if ($updateFlag) {

lib/Games/Axmud/Obj/WorldModel.pm  view on Meta::CPAN

    sub resetExclusiveProfiles {

        # Called by GA::Win::Map->enableRoomsColumn
        # Resets the list of exclusive profile for one or more room objects
        #
        # Expected arguments
        #   $updateFlag - Flag set to TRUE if all Automapper windows using this world model should
        #                   be updated now, FALSE if not (in which case, they can be updated later
        #                   by the calling function, when it is ready)
        #
        # Optional argument
        #   @roomList   - A list of room GA::ModelObj::Room objects. If the list is empty, no rooms
        #                   are updated
        #
        # Return values
        #   'undef' on improper arguments or if @roomList is empty
        #   1 otherwise

        my ($self, $updateFlag, @roomList) = @_;

        # Local variables
        my @redrawList;

        # Check for improper arguments
        if (! defined $updateFlag) {

            return $axmud::CLIENT->writeImproper($self->_objClass . '->resetExclusiveProfiles', @_);
        }

        # Do nothing if @roomList is empty
        if (! @roomList) {

            return undef;
        }

        # Update each room in turn
        foreach my $roomObj (@roomList) {

            $roomObj->ivEmpty('exclusiveHash');
        }

        # Update any GA::Win::Map objects using this world model (if allowed)
        if ($updateFlag) {

            foreach my $roomObj (@roomList) {

                push (@redrawList, 'room', $roomObj);
            }

            foreach my $mapWin ($self->collectMapWins()) {

                # Redraw the rooms
                $mapWin->markObjs(@redrawList);
                $mapWin->doDraw();
            }
        }

        return 1;
    }

    sub updateInvRepExit {

        # Called by $self->deleteObj
        # Each room model object keeps track of which rooms use it as the destination room for an
        #   involuntary exit pattern/repulse exit pattern
        # When a room is deleted, this function is called to remove an entry in the destination
        #   room's hash
        #
        # Expected arguments
        #   $destRoomObj    - The room to update
        #   $deleteRoomObj  - The room to be deleted
        #
        # Return values
        #   'undef' on improper arguments
        #   1 otherwise

        my ($self, $destRoomObj, $deleteRoomObj, $check) = @_;

        # Check for improper arguments
        if (! defined $destRoomObj || ! defined $deleteRoomObj || defined $check) {

            return $axmud::CLIENT->writeImproper($self->_objClass . '->updateInvRepExit', @_);
        }

        # Update IVs
        $destRoomObj->ivDelete('invRepExitHash', $deleteRoomObj->number);

        return 1;
    }

    sub addInvoluntaryExit {

        # Called by GA::EditWin::ModelObj::Room->saveChanges,
        #   GA::Win::Map->addInvoluntaryExitCallback or any other function
        # Adds an involuntary exit pattern and, optionally, a direction (or a room model number)
        #   which identifies the destination room
        #
        # Expected arguments
        #   $roomObj        - The room model object (GA::ModelObj::Room) to update
        #   $pattern        - The involuntary exit pattern to add
        #
        # Optional arguments
        #   $value          - The direction of movement, or the number of the destination room, or
        #                       'undef'
        #
        # Return values
        #   'undef' on improper arguments
        #   1 otherwise

        my ($self, $roomObj, $pattern, $value, $check) = @_;

        # Local variables
        my $destRoomObj;

        # Check for improper arguments
        if (! defined $roomObj || ! defined $pattern  || defined $check) {

            return $axmud::CLIENT->writeImproper($self->_objClass . '->addInvoluntaryExit', @_);
        }

        # Update IVs

lib/Games/Axmud/Obj/WorldModel.pm  view on Meta::CPAN


        # Called by GA::EditWin::Exit->saveChanges
        # Each room model object keeps track of the exits which use the room as a random destination
        #   (but only when GA::Obj::Exit->randomType is 'room_list')
        # This function is called to add an exit to the room's hash
        #
        # Expected arguments
        #   $roomObj    - The room to update
        #   $exitObj    - The exit (belonging to another room) which now uses $roomObj as one of its
        #                   random destinations
        #
        # Return values
        #   'undef' on improper arguments
        #   1 otherwise

        my ($self, $roomObj, $exitObj, $check) = @_;

        # Check for improper arguments
        if (! defined $roomObj || ! defined $exitObj || defined $check) {

            return $axmud::CLIENT->writeImproper($self->_objClass . '->addRandomDestination', @_);
        }

        $roomObj->ivAdd('randomExitHash', $exitObj->number, undef);

        return 1;
    }

    sub removeRandomDestination {

        # Called by GA::EditWin::Exit->saveChanges
        # Each room model object keeps track of the exits which use the room as a random destination
        #   (but only when GA::Obj::Exit->randomType is 'room_list')
        # This function is called to remove an exit from the room's hash
        #
        # Expected arguments
        #   $roomObj    - The room to update
        #   $exitObj    - The exit (belonging to another room) which no longer uses $roomObj as one
        #                   of its random destinations
        #
        # Return values
        #   'undef' on improper arguments
        #   1 otherwise

        my ($self, $roomObj, $exitObj, $check) = @_;

        # Check for improper arguments
        if (! defined $roomObj || ! defined $exitObj || defined $check) {

            return $axmud::CLIENT->writeImproper(
                $self->_objClass . '->removeRandomDestination',
                @_,
            );
        }

        $roomObj->ivDelete('randomExitHash', $exitObj->number, undef);

        return 1;
    }

    sub updateRandomExit {

        # Called by $self->deleteObj when a room is deleted, which has an incoming random exit. This
        #   function removes the room from the exit's list of random destination rooms
        #
        # Expected arguments
        #   $exitObj    - The exit object to update
        #   $roomObj    - The room which is being deleted
        #
        # Return values
        #   'undef' on improper arguments
        #   1 otherwise

        my ($self, $exitObj, $roomObj, $check) = @_;

        # Local variables
        my (@roomList, @modList);

        # Check for improper arguments
        if (! defined $exitObj || ! defined $roomObj || defined $check) {

            return $axmud::CLIENT->writeImproper($self->_objClass . '->updateRandomExit', @_);
        }

        # Import the IV
        @roomList = $exitObj->randomDestList;

        # Remove $roomObj from the exit's list of random destinations
        foreach my $roomNum (@roomList) {

            if ($roomNum ne $roomObj->number) {

                push (@modList, $roomNum);
            }
        }

        # Update the IV
        $exitObj->ivPoke('randomDestList', @modList);

        return 1;
    }

    sub setWildernessRoom {

        # Can be called by anything
        # Sets a room's ->wildMode, removing any existing exit objects and redrawing as required
        #
        # Expected arguments
        #   $session    - The calling function's GA::Session
        #   $updateFlag - Flag set to TRUE if all Automapper windows using this world model should
        #                   be updated now, FALSE if not (in which case, they can be updated later
        #                   by the calling function, when it is ready)
        #   $mode       - The new wilderness mode, one of the strings 'normal', 'border' or 'wild'
        #                   (it doesn't matter if any specified room already has that mode)
        #
        # Optional arguments
        #   @roomList   - A list of GA::ModelObj::Room objects to update (can be an empty list)
        #
        # Return values
        #   'undef' on improper arguments
        #   1 otherwise

lib/Games/Axmud/Obj/WorldModel.pm  view on Meta::CPAN

        # Expected arguments
        #   $session        - The calling function's GA::Session
        #   $updateFlag     - Flag set to TRUE if all Automapper windows using this world model
        #                       should be updated now, FALSE if not (in which case, they can be
        #                       updated later by the calling function, when it is ready)
        #   $exitObj        - The GA::Obj::Exit to modify
        #   $index          - The index of the bend to remove (the bend nearest to the start of the
        #                       exit's list of bend coordinates is numbered 0)
        #
        # Return values
        #   'undef' on improper arguments
        #   1 otherwise

        my ($self, $session, $updateFlag, $exitObj, $index, $check) = @_;

        # Local variables
        my $roomObj;

        # Check for improper arguments
        if (
            ! defined $session || ! defined $updateFlag || ! defined $exitObj || ! defined $index
            || defined $check
        ) {
            return $axmud::CLIENT->writeImproper($self->_objClass . '->removeExitBend', @_);
        }

        # GA::Obj::Exit->bendOffsetList is in the form (x, y, x, y...). Remove a single pair of
        #   (x, y) coordinates; e.g. if $index = 2, remove the 5th and 6th coordinates
        $index *= 2;
        $exitObj->ivSplice('bendOffsetList', $index, 2);

        # Check whether the exit's destination and departure rooms are aligned. If so, we can
        #   restore the exit to a non-broken status
        if (! $exitObj->bendOffsetList && $self->checkRoomAlignment($session, $exitObj)) {

            $self->restoreBrokenExit(
                $session,
                FALSE,              # Don't update automapper windows now
                $exitObj,
                TRUE,               # We've already called $self->checkRoomAlignment
            );
        }

        # Update any GA::Win::Map objects using this world model (if allowed)
        if ($updateFlag) {

            # Get the exit's parent room
            $roomObj = $self->ivShow('modelHash', $exitObj->parent);

            foreach my $mapWin ($self->collectMapWins()) {

                # Redraw the room
                $mapWin->markObjs('room', $roomObj);
                $mapWin->doDraw();
            }
        }

        return 1;
    }

    sub updateExitBends {

        # Called by $self->moveRoomsLabels
        # When a room is dragged to a new position in the (same) regionmap, we must update the
        #   position of any exit bends
        #
        # Expected arguments
        #   $adjustXPos, $adjustYPos, $adjustZPos
        #                   - The direction of the room's movement, in gridblocks
        #   $regionmapObj   - The regionmap in which the exit's room has been moved
        #   $exitObj        - The GA::Obj::Exit whose bends must be updated
        #
        # Optional arguments
        #   $twinExitObj    - $exitObj's twin, if it has one ('undef' otherwise)
        #
        # Return values
        #   'undef' on improper arguments
        #   1 otherwise

        my (
            $self, $adjustXPos, $adjustYPos, $adjustZPos, $regionmapObj, $exitObj, $twinExitObj,
            $check,
        ) = @_;

        # Local variables
        my (@offsetList, @newList);

        # Check for improper arguments
        if (
            ! defined $adjustXPos || ! defined $adjustYPos || ! defined $adjustZPos
            || ! defined $exitObj || defined $check
        ) {
            return $axmud::CLIENT->writeImproper($self->_objClass . '->updateExitBends', @_);
        }

        # If the room has moved up or down, remove bends altogether
        if ($adjustZPos) {

            $exitObj->ivEmpty('bendOffsetList');
            # (Also for the twin exit, if there is one)
            if ($twinExitObj) {

                $twinExitObj->ivEmpty('bendOffsetList');
            }

        # Otherwise, use the room's new position to update the bend's position
        # (We don't update the twin - if that room has also been dragged, this function will be
        #   called again to update its bends)
        } else {

            $adjustXPos *= $regionmapObj->blockWidthPixels;
            $adjustYPos *= $regionmapObj->blockHeightPixels;

            @offsetList = $exitObj->bendOffsetList;
            do {

                # @offsetList is in the form (x, y, x, y...)
                push (@newList, ((shift @offsetList) - $adjustXPos));
                push (@newList, ((shift @offsetList) - $adjustYPos));

            } until (! @offsetList);

            $exitObj->ivPoke('bendOffsetList', @newList);
        }

        return 1;
    }

    # Modify model objects - labels

    sub updateLabel {

        # Called by GA::Win::Map->setLabelCallback and ->promptConfigLabel
        # Sets the specified label's ->name IV (containing the text displayed) and redraw the label
        #   (if allowed)
        #
        # Expected arguments
        #   $updateFlag - Flag set to TRUE if all Automapper windows using this world model should
        #                   be updated now, FALSE if not (in which case, they can be updated later
        #                   by the calling function, when it is ready)
        #   $session    - The calling GA::Session
        #   $labelObj   - The GA::Obj::MapLabel to modify
        #   $name       - The new text for the label
        #
        # Optional arguments
        #   $style      - The new map label style (if 'undef', the label starts using its own IVs
        #                   to set a style)
        #
        # Return values
        #   'undef' on improper arguments
        #   1 otherwise

        my ($self, $updateFlag, $session, $labelObj, $name, $style, $check) = @_;

        # Check for improper arguments
        if (
            ! defined $updateFlag || ! defined $session || ! defined $labelObj || ! defined $name
            || defined $check
        ) {
            return $axmud::CLIENT->writeImproper($self->_objClass . '->updateLabel', @_);
        }

        # Update IVs
        $labelObj->ivPoke('name', $name);
        if (defined $style) {
            $labelObj->set_style($session, $style);
        } else {
            $labelObj->reset_style();
        }

        # Update any GA::Win::Map objects using this world model (if allowed)
        if ($updateFlag) {

            foreach my $mapWin ($self->collectMapWins()) {

                # Redraw the label
                $mapWin->markObjs('label', $labelObj);
                $mapWin->doDraw();
            }
        }

        return 1;
    }

    # Room flag methods

    sub setupRoomFlags {

        # Called by $self->new to initialise the model's room filter and room flag IVs
        # Also called by $self->resetRoomFlags
        #

lib/Games/Axmud/Obj/WorldModel.pm  view on Meta::CPAN

            if ($newObj) {

                $newObj->ivPoke('shortName', $short);
                $newObj->ivPoke('descrip', $descrip);
                $newObj->ivPoke('priority', $count);
                $newObj->ivPoke('filter', $filter);
                $newObj->ivPoke('colour', $colour);

                $self->ivAdd('roomFlagHash', $name, $newObj);
                push (@orderedList, $name);
            }

        } until (! @initList);

        $self->ivPoke('roomFlagOrderedList', @orderedList);

        # Operation complete
        return 1;
    }

    sub resetRoomFlags {

        # Called by GA::EditWin::WorldModel->roomFlags1Tab
        # Resets the world model's room flags to their default state, eliminating any custom room
        #   flags
        # Checks every room in the model, removing any room flags that no longer exist
        #
        # Expected arguments
        #   $session    - The calling function's GA::Session
        #
        # Return values
        #   'undef' on improper arguments
        #   1 otherwise

        my ($self, $session, $check) = @_;

        # Check for improper arguments
        if (! defined $session || defined $check) {

            return $axmud::CLIENT->writeImproper($self->_objClass . '->resetRoomFlags', @_);
        }

        # Reset the IVs
        $self->setupRoomFlags($session);

        # Check every room in the model, eliminating custom room flags that no longer exist
        foreach my $roomObj ($self->ivValues('roomModelHash')) {

            foreach my $roomFlag ($roomObj->ivKeys('roomFlagHash')) {

                if (! $self->ivExists('roomFlagHash', $roomFlag)) {

                    $roomObj->ivDelete('roomFlagHash', $roomFlag);
                }
            }
        }

        return 1;
    }

    sub updateRoomFlags {

        # Called by GA::Obj::File->updateExtractedData in order to update the room flags stored in
        #   this world model to those used in a more recent version of Axmud
        #
        # Expected arguments
        #   $session    - The calling function's GA::Session
        #
        # Return values
        #   'undef' on improper arguments
        #   1 otherwise

        my ($self, $session, $check) = @_;

        # Local variables
        my (
            @initList,
            %newApplyHash,
        );

        # Check for improper arguments
        if (defined $check) {

            return $axmud::CLIENT->writeImproper($self->_objClass . '->updateRoomFlags', @_);
        }

        # Update $self->roomFilterApplyHash. Add any new filters, and remove any defunct filters
        #   (the latter will probably never happen, but there's no harm in checking)
        foreach my $filter ($axmud::CLIENT->constRoomFilterList) {

            if ($self->ivExists('roomFilterApplyHash', $filter)) {

                # Keep the current setting
                $newApplyHash{$filter} = $self->ivShow('roomFilterApplyHash', $filter);

            } else {

                # New filter
                $newApplyHash{$filter} = FALSE;
            }
        }

        $self->ivPoke('roomFilterApplyHash', %newApplyHash);

        # Update $self->roomFlagHash and ->roomFlagOrderedList. Add any new room flag objects, but
        #   don't remove any defunct room flags (as the rooms in this world model might be using
        #   them)
        @initList = $axmud::CLIENT->constRoomFlagList;
        do {

            my ($name, $short, $filter, $colour, $descrip, $count, $index, $newObj);

            $name = shift @initList;
            $short = shift @initList;
            $filter = shift @initList;
            $colour = shift @initList;
            $descrip = shift @initList;

            if (! $self->ivExists('roomFlagHash', $name)) {

                # Go through the existing ordered list of room flags, and find the position of the

lib/Games/Axmud/Obj/WorldModel.pm  view on Meta::CPAN

        { my $self = shift; return %{$self->{roomTerrainInitHash}}; }
    sub roomTerrainHash
        { my $self = shift; return %{$self->{roomTerrainHash}}; }

    sub paintFromTitleHash
        { my $self = shift; return %{$self->{paintFromTitleHash}}; }
    sub paintFromDescripHash
        { my $self = shift; return %{$self->{paintFromDescripHash}}; }
    sub paintFromExitHash
        { my $self = shift; return %{$self->{paintFromExitHash}}; }
    sub paintFromObjHash
        { my $self = shift; return %{$self->{paintFromObjHash}}; }
    sub paintFromRoomCmdHash
        { my $self = shift; return %{$self->{paintFromRoomCmdHash}}; }

    sub currentRoomMode
        { $_[0]->{currentRoomMode} }
    sub roomInteriorMode
        { $_[0]->{roomInteriorMode} }
    sub roomInteriorXOffset
        { $_[0]->{roomInteriorXOffset} }
    sub roomInteriorYOffset
        { $_[0]->{roomInteriorYOffset} }

    sub drawExitMode
        { $_[0]->{drawExitMode} }
    sub obscuredExitFlag
        { $_[0]->{obscuredExitFlag} }
    sub obscuredExitRedrawFlag
        { $_[0]->{obscuredExitRedrawFlag} }
    sub obscuredExitRadius
        { $_[0]->{obscuredExitRadius} }
    sub maxObscuredExitRadius
        { $_[0]->{maxObscuredExitRadius} }
    sub drawOrnamentsFlag
        { $_[0]->{drawOrnamentsFlag} }
    sub horizontalExitLengthBlocks
        { $_[0]->{horizontalExitLengthBlocks} }
    sub verticalExitLengthBlocks
        { $_[0]->{verticalExitLengthBlocks} }
    sub maxExitLengthBlocks
        { $_[0]->{maxExitLengthBlocks} }
    sub drawBentExitsFlag
        { $_[0]->{drawBentExitsFlag} }

    sub matchTitleFlag
        { $_[0]->{matchTitleFlag} }
    sub matchDescripFlag
        { $_[0]->{matchDescripFlag} }
    sub matchDescripCharCount
        { $_[0]->{matchDescripCharCount} }
    sub matchExitFlag
        { $_[0]->{matchExitFlag} }
    sub analyseDescripFlag
        { $_[0]->{analyseDescripFlag} }
    sub matchSourceFlag
        { $_[0]->{matchSourceFlag} }
    sub matchVNumFlag
        { $_[0]->{matchVNumFlag} }

    sub updateTitleFlag
        { $_[0]->{updateTitleFlag} }
    sub updateDescripFlag
        { $_[0]->{updateDescripFlag} }
    sub updateExitFlag
        { $_[0]->{updateExitFlag} }
    sub updateSourceFlag
        { $_[0]->{updateSourceFlag} }
    sub updateVNumFlag
        { $_[0]->{updateVNumFlag} }
    sub updateRoomCmdFlag
        { $_[0]->{updateRoomCmdFlag} }
    sub updateOrnamentFlag
        { $_[0]->{updateOrnamentFlag} }

    sub assistedMovesFlag
        { $_[0]->{assistedMovesFlag} }
    sub assistedBreakFlag
        { $_[0]->{assistedBreakFlag} }
    sub assistedPickFlag
        { $_[0]->{assistedPickFlag} }
    sub assistedUnlockFlag
        { $_[0]->{assistedUnlockFlag} }
    sub assistedOpenFlag
        { $_[0]->{assistedOpenFlag} }
    sub assistedCloseFlag
        { $_[0]->{assistedCloseFlag} }
    sub assistedLockFlag
        { $_[0]->{assistedLockFlag} }
    sub protectedMovesFlag
        { $_[0]->{protectedMovesFlag} }
    sub superProtectedMovesFlag
        { $_[0]->{superProtectedMovesFlag} }
    sub craftyMovesFlag
        { $_[0]->{craftyMovesFlag} }

    sub setTwinOrnamentFlag
        { $_[0]->{setTwinOrnamentFlag} }

    sub newRoomScriptList
        { my $self = shift; return @{$self->{newRoomScriptList}}; }
    sub arriveScriptList
        { my $self = shift; return @{$self->{arriveScriptList}}; }

    sub countVisitsFlag
        { $_[0]->{countVisitsFlag} }
    sub allowModelScriptFlag
        { $_[0]->{allowModelScriptFlag} }
    sub allowRoomScriptFlag
        { $_[0]->{allowRoomScriptFlag} }
    sub intelligentExitsFlag
        { $_[0]->{intelligentExitsFlag} }
    sub followAnchorFlag
        { $_[0]->{followAnchorFlag} }
    sub capitalisedRoomTagFlag
        { $_[0]->{capitalisedRoomTagFlag} }
    sub showTooltipsFlag
        { $_[0]->{showTooltipsFlag} }
    sub showNotesFlag
        { $_[0]->{showNotesFlag} }
    sub explainGetLostFlag
        { $_[0]->{explainGetLostFlag} }
    sub disableUpdateModeFlag
        { $_[0]->{disableUpdateModeFlag} }
    sub updateExitTagFlag
        { $_[0]->{updateExitTagFlag} }
    sub drawRoomEchoFlag
        { $_[0]->{drawRoomEchoFlag} }
    sub allowTrackAloneFlag
        { $_[0]->{allowTrackAloneFlag} }
    sub showAllPrimaryFlag
        { $_[0]->{showAllPrimaryFlag} }
    sub allowCtrlCopyFlag
        { $_[0]->{allowCtrlCopyFlag} }

    sub autoCompareMode
        { $_[0]->{autoCompareMode} }
    sub autoCompareAllFlag
        { $_[0]->{autoCompareAllFlag} }
    sub autoCompareMax
        { $_[0]->{autoCompareMax} }
    sub autoSlideMode
        { $_[0]->{autoSlideMode} }
    sub autoSlideMax
        { $_[0]->{autoSlideMax} }
    sub autoRescueFlag
        { $_[0]->{autoRescueFlag} }
    sub autoRescueFirstFlag
        { $_[0]->{autoRescueFirstFlag} }
    sub autoRescuePromptFlag
        { $_[0]->{autoRescuePromptFlag} }
    sub autoRescueNoMoveFlag
        { $_[0]->{autoRescueNoMoveFlag} }
    sub autoRescueVisitsFlag
        { $_[0]->{autoRescueVisitsFlag} }
    sub autoRescueForceFlag
        { $_[0]->{autoRescueForceFlag} }

    sub lastFilePath
        { $_[0]->{lastFilePath} }
    sub lastVirtualAreaPath
        { $_[0]->{lastVirtualAreaPath} }
    sub trackPosnFlag
        { $_[0]->{trackPosnFlag} }
    sub trackingSensitivity
        { $_[0]->{trackingSensitivity} }
    sub avoidHazardsFlag
        { $_[0]->{avoidHazardsFlag} }
    sub postProcessingFlag
        { $_[0]->{postProcessingFlag} }
    sub quickPathFindFlag
        { $_[0]->{quickPathFindFlag} }
    sub autocompleteExitsFlag
        { $_[0]->{autocompleteExitsFlag} }
    sub collectCheckedDirsFlag
        { $_[0]->{collectCheckedDirsFlag} }
    sub drawCheckedDirsFlag
        { $_[0]->{drawCheckedDirsFlag} }
    sub checkableDirMode
        { $_[0]->{checkableDirMode} }

    sub adjacentMode
        { $_[0]->{adjacentMode} }
    sub adjacentCount
        { $_[0]->{adjacentCount} }
    sub updateBoundaryHash
        { my $self = shift; return %{$self->{updateBoundaryHash}}; }
    sub deleteBoundaryHash
        { my $self = shift; return %{$self->{deleteBoundaryHash}}; }
    sub updatePathHash
        { my $self = shift; return %{$self->{updatePathHash}}; }
    sub updateDelayFlag
        { $_[0]->{updateDelayFlag} }
    sub checkLevelsHash
        { my $self = shift; return %{$self->{checkLevelsHash}}; }

    sub mudlibPath
        { $_[0]->{mudlibPath} }
    sub mudlibExtension
        { $_[0]->{mudlibExtension} }

    sub painterObj
        { $_[0]->{painterObj} }
    sub constPainterIVList
        { my $self = shift; return @{$self->{constPainterIVList}}; }
    sub paintAllRoomsFlag
        { $_[0]->{paintAllRoomsFlag} }
    sub quickPaintMultiFlag
        { $_[0]->{quickPaintMultiFlag} }

    sub searchMaxMatches
        { $_[0]->{searchMaxMatches} }
    sub searchMaxObjects
        { $_[0]->{searchMaxObjects} }
    sub searchSelectRoomsFlag
        { $_[0]->{searchSelectRoomsFlag} }
    sub locateMaxObjects
        { $_[0]->{locateMaxObjects} }
    sub locateRandomInRegionFlag
        { $_[0]->{locateRandomInRegionFlag} }
    sub locateRandomAnywhereFlag
        { $_[0]->{locateRandomAnywhereFlag} }

    sub pathFindStepLimit
        { $_[0]->{pathFindStepLimit} }

    sub drawPauseNum
        { $_[0]->{drawPauseNum} }
    sub recalculatePauseNum
        { $_[0]->{recalculatePauseNum} }

    sub mapFont
        { $_[0]->{mapFont} }
    sub roomTagRatio
        { $_[0]->{roomTagRatio} }
    sub roomGuildRatio
        { $_[0]->{roomGuildRatio} }
    sub exitTagRatio
        { $_[0]->{exitTagRatio} }
    sub labelRatio
        { $_[0]->{labelRatio} }
    sub roomTextRatio
        { $_[0]->{roomTextRatio} }

    sub blockUnselectFlag
        { $_[0]->{blockUnselectFlag} }
}

# Package must return a true value
1



( run in 1.713 second using v1.01-cache-2.11-cpan-39bf76dae61 )